一、需求

1.分析:用react开发一个类似bootstrap4中的card组件http://v4-alpha.getbootstrap.com/components/card/,界面类似如下:

2.确定发目标:

3.确定开发顺序

4.开发流程介绍

测试采用TDD

二、代码

1.Card.js

 var React = require('react/addons');

 var Card = React.createClass({
getInitialState: function() {
return this.props.content;
},
handleClick: function() {
this.setState({
blocks : [{
title: "Allen Iverson(已关注)",
subtitle: "PG",
text: "Cool player",
links: [{
url:"http://www.163.com",
name:"链接1"
}, {
url:"http://www.g.cn",
name:"链接2"
}
]
}]
})
},
render: function(){
var content = this.state; var blocks = [];
for(var i = 0; i < content.blocks.length; i++){
var block = content.blocks[i];
var links = [];
for(var i = 0; i < block.links.length; i++){
links.push(<a onClick={this.handleClick} className="card-link" href={block.links[i].url}>{block.links[i].name}</a>);
}
blocks.push(<div className="card-block">
<h4 className="card-title">{block.title}</h4>
<h6 className="card-subtitle">{block.subtitle}</h6>
<p className="card-text">{block.text}</p>
<p>
{links}
</p>
</div>
);
} var listGroup = [];
for(var i = 0; i < content.listGroup.length; i++){
listGroup.push(<li className="list-group-item">{content.listGroup[i]}</li>);
} var option = this.props.option ? "card text-xs-" + this.props.option : "card";
return <div className="container-fluid">
<div className="row">
<div className="col-sm-4">
<div className={option}>
<div className="card-header">{content.header}</div>
<img className="card-img-top" src={content.imgTop.url} alt={content.imgTop.alt}></img>
{blocks}
<ul className="list-group list-group-flush">
{listGroup}
</ul>
<img className="card-img-bottom" src={content.imgBottom.url} alt={content.imgBottom.alt}></img>
<div className="card-footer">{content.footer}</div>
</div>
</div>
</div>
</div>
}
}) module.exports = Card

2.test.jsx

 var React = require('react/addons');
var jasmineReact = require('jasmine-react-helpers');
var TestUtils = React.addons.TestUtils;
var Card = require('./Card.jsx'); describe('Card component', function(){ var card;
var content; beforeEach(function(){
//渲染
var blocks = [
{
title: "Allen Iverson",
subtitle: "PG",
text: "Cool player",
links: [{
url:"http://www.163.com",
name:"链接1"
}, {
url:"http://www.g.cn",
name:"链接2"
}
]
}
];
var header = "76ers";
var footer = "mvp";
var listGroup = ["艾弗森1996年6月26日被费城76人队选中,成为NBA状元秀,绰号答案(The Answer)","场均出战41.1分钟,获得26.7分、6.2次助攻和2.2次抢断"];
var imgTop = {
url: "http://a1.hoopchina.com.cn/attachment/Day_100424/43_3842044_665ae051136b4b8.jpg",
alt: "dribble"
};
var imgBottom = {
url: "http://www.onlinedown.net/bigsoftimg/androidimg/260000/255860_0.jpg",
alt: "crossover"
}
var content = {
blocks: blocks,
header: header,
footer: footer,
listGroup: listGroup,
imgBottom: imgBottom,
imgTop: imgTop
}
card = TestUtils.renderIntoDocument(<Card content={content} option="center"></Card>);
}) afterEach(function(){
React.unmountComponentAtNode(React.findDOMNode(card))
}) it('should exist', function(){
expect(!!React.findDOMNode(card)).toBe(true)
//card = TestUtils.renderIntoDocument(<Card content={content}></Card>);
//expect(React.findDOMNode(card).textContent).toContain('Hello world')
}); it('should have correct structure', function(){
//测试
//card = TestUtils.renderIntoDocument(<Card content={content}></Card>);
var content = React.findDOMNode(card).textContent;
expect(content).toContain("Allen");
expect(content).toContain("76ers");
expect(content).toContain("mvp");
expect(content).toContain("艾弗森");
expect(React.findDOMNode(card).getElementsByTagName("img")[0].alt).toContain("dribble");
expect(React.findDOMNode(card).getElementsByTagName("img")[1].alt).toContain("crossover"); }); it('should have correct style', function() {
var cardBox = React.findDOMNode(card).getElementsByClassName("card");
expect(!!cardBox.length).toBe(true);
}); it('should correctly use options', function() {
var cardBox = React.findDOMNode(card).getElementsByClassName("text-xs-center");
expect(!!cardBox.length).toBe(true);
}); it('should be response', function() {
TestUtils.Simulate.click(React.findDOMNode(card).getElementsByTagName("a")[0]);
var content = React.findDOMNode(card).textContent;
expect(content).toContain("已关注");
});
})

3.show.jsx

 var React = require('react/addons');
var Card = require('./Card.jsx'); var blocks = [
{
title: "Allen Iverson",
subtitle: "PG",
text: "Cool player",
links: [{
url:"http://www.163.com",
name:"链接1"
}, {
url:"http://www.g.cn",
name:"链接2"
}
]
}
];
var header = "76ers";
var footer = "mvp";
var listGroup = ["艾弗森1996年6月26日被费城76人队选中,成为NBA状元秀,绰号答案(The Answer)","场均出战41.1分钟,获得26.7分、6.2次助攻和2.2次抢断"];
var imgTop = {
url: "http://a1.hoopchina.com.cn/attachment/Day_100424/43_3842044_665ae051136b4b8.jpg",
alt: "dribble"
};
var imgBottom = {
url: "http://www.onlinedown.net/bigsoftimg/androidimg/260000/255860_0.jpg",
alt: "crossover"
}
var content = {
blocks: blocks,
header: header,
footer: footer,
listGroup: listGroup,
imgBottom: imgBottom,
imgTop: imgTop
}
React.render(<Card content={content} option="right"></Card>, document.body);

四、运行结果(bootstrap的css无效果)

源码:http://files.cnblogs.com/files/shamgod/BootstrapCard.zip

React开发项目例子的更多相关文章

  1. react实战项目开发(2) react几个重要概念以及JSX语法

    前言 前面我们已经学习了利用官方脚手架搭建一套可以应用在生产环境下的React开发环境.那么今天这篇文章主要先了解几个react重要的概念,以及讲解本文的重要知识JSX语法 React重要概念 [思想 ...

  2. Expo大作战(三)--针对已经开发过react native项目开发人员有针对性的介绍了expo,expo的局限性,开发时项目选型注意点等

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  3. react 开发 PC 端项目(一)项目环境搭建 及 处理 IE8 兼容问题

    步骤一:项目环境搭建 首先,你不应该使用 React v15 或更高版本.使用仍然支持 IE8 的 React v0.14 即可. 技术选型: 1.react@0.14 2.bootstrap3 3. ...

  4. react 前端项目技术选型、开发工具、周边生态

    react 前端项目技术选型.开发工具.周边生态 声明:这不是一篇介绍 React 基础知识的文章,需要熟悉 React 相关知识 主架构:react, react-router, redux, re ...

  5. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 “8小时内拼工作,8小时外拼成长 ...

  6. React Native 项目运行在 Web 浏览器上面

    React Native 的出现,让前端工程师拥有了使用 JavaScript 编写原生 APP 的能力.相比之前的 Web app 来说,对于性能和用户体验提升了非常多. 但是 React Nati ...

  7. 用Inferno代替React开发高性能响应式WEB应用

    什么是Inferno Inferno可以看做是React的另一个精简.高性能实现.它的使用方式跟React基本相同,无论是JSX语法.组件的建立.组件的生命周期,还是与Redux或Mobx的配合.路由 ...

  8. Immutable.js 以及在 react+redux 项目中的实践

    来自一位美团大牛的分享,相信可以帮助到你. 原文链接:https://juejin.im/post/5948985ea0bb9f006bed7472?utm_source=tuicool&ut ...

  9. React开发实时聊天招聘工具 -第一章

    第一章 课程道学 6个页面 弱化css Antd-mobile作为组件库 Redux 状态管理 React-Router 路由 Axios异步请求 后端Express框架 Socket.io 数据库: ...

随机推荐

  1. Zendframework application 引导过程

    Applications 会期望用户提供一个配置好的ServiceManager.提供以下服务: 1.EventManager 2.ModuleManager 3.Request 4.Response ...

  2. 未能加载文件或程序集“Report.Basic”或它的某一个依赖项。试图加载格式不正确的程序

    出现问题如下: 解决办法: 这是由于没有开启32位程序兼容模式 具体操作如下:找到对应的程序池--------高级设置-------修改“启用32位应用程序”状态修改为true

  3. 【js】undefined

    alert(a); function name(parameters) { alert(parameters); } var a; name(a); ---输出结果--- underfind unde ...

  4. iOS中Cell高度如何能够自动适应需要显示的内容

    本文的代码例子 : "Cell行高自适应.zip" http://vdisk.weibo.com/s/Gb9Mt 下面我们来看看代码.我需要一个第三方库EGO异步下载.addtio ...

  5. 自定义控件(模仿微信ToggleButton控件)

    弄过android开发的都知道,系统有一个默认的ToggleButton,但很多人都觉得他很难看,当然也包括我.如果你感觉他不难看,那你就继续使用系统的吧,这篇文章对你来说是多余的了. 今天来写一个模 ...

  6. windows下SSH客户端远程访问Linux出现错误

  7. Qt html 界面混合编程

    Qt部分 项目文件.pro Qt += webenginewidgets webchannel 创建WebEngineView #include <QtWebEngineWidgets> ...

  8. 怎么查看其它apk里面的布局代码及资源

    今天才看到的好方法, 将你要的apk文件的后缀名改为zip,解压就可以了. --------------------------------- 提示:有时候系统会自动隐藏你的后缀名的,这时候就需要你将 ...

  9. Python求算数平方根和约数

    一.求算术平方根 a=0 x=int(raw_input('Enter a number:')) if x >= 0: while a*a < x: a = a + 1 if a*a != ...

  10. bzoj 4010: [HNOI2015]菜肴制作 拓扑排序

    题目链接: 题目 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB 问题描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴 ...