上次更新: 2016-08-26 19:31:46
标签: 实战前端
当今的前端正处于技术爆发期,这个阶段涌现很多优秀的编程思想以及框架,本文所介绍的react就是 前端的一种框架,它使用单向数据绑定以及jsx语法糖,通过它提供的特性,可以构建去区别于以前传统 型的网页。
单页模式区别于传统模式开发,比如用户的登录状态、数据列表的缓存,传统类型的MVC设计模式中,后端语言(Java、PHP......)中,浏览器发起url请求,后端根据请求的路径和参数,后端对数据进行处理(从数据库中拿出数据、请求第三方接口等......),然后进行页面数据填充后返回完整的HTML数据,浏览器拿到这些html元素后进行页面渲染。
单页应用模式的区别在于请求进行接口化,开发过Android或者iOS的应该知道,客户端处理数据状态,操作UI控件,与后端进行网络通信获取数据通信。单页应用的开发就是基于这种模式,那么处理数据状态的任务就落到前端的头上来了,react提供视图渲染的优化,但是数据的状态管理就成了一个问题,比如用户的数据,交由那个组件去控制,怎么进行交互,这就成了一个问题。Facebook提出了Flux设计模型来解决这个问题,用store来存放数据源,通过action、reducer来操作数据,来保证数据的单一性。
但是Facebook只是提出了这一种设计思想,没有开发相应的框架,于是就诞生了很多第三方实现,Redux就是其中一种,它不是完全采用Flux规范模式,它提出了自己的设计思想,Redux也就成了和React搭配的优秀的状态工具。
代码生成工具使用Yeoman,Yeoman是一个代码generators工具,它提供很多第三方generators,通过它,我们可以很方便的构建一个初始化项目,点击访问Yeoman
项目使用react+redux构建,所以这里选择generator-redux-stack
来作为生成模板。终端下使用如下命令:
#安装yeoman
npm install yo -g
#安装generators
npm install -g generator-redux-stack
#创建目录并进入
mkdir [xxx] && cd [xxx]
#使用yo创建项目框架
yo redux-stack
执行完成后会看到下图
填写相应的项目描述信息,Yeoman会自动创建文件,并且安装依赖
如果网络较慢可以Ctrl+C
停止安装,使用cnpm国内镜像安装(#滑稽)。
稍等一会出现如下界面就说明完成了
在终端输入
npm start
浏览器端打开http://localhost:3000
可以看到生成器提供的模板
好了,接下来就可以开始编码了。:)
目录结构由
redux-stack
控制
| 目录名 | 描述 | | ----- | :--- | |build|项目主html文件存放位置| |dist|项目编译目录位置| |node_modules|npm包存放位置| |server|项目运行时服务器环境| |src|项目源码目录,代码主要存放位置| | ----actions|redux action存放目录| | ----components|react组件存放目录| | ----config|react-router主要配置文件| | ----container|react页面(组件拼贴)存放位置| | ----reducers|redux reducer存放位置| | ----store|redux store定义存放位置| | ----style|样式文件存放位置| | ----utils|开发调试工具配置| |test|测试脚本存放目录|
在container
目录新创建一个Home.js
文件
// src/containers/Home.js
import React, { Component } from 'react';
export default class Home extends Component {
render () {
return (
<div>
这是主页
</div>
)
}
}
这里创建了一个组件,组件渲染了一个div
标签,里面是一行文字。render
使用了jsx的语法糖。
修改config
目录下面的routes.js
文件,需要引入Home组件,并且将其挂载到根节点。
// src/config/routes.js
import Home from '../containers/Home.js';
export default (
<Route path="/" component={Home} />
);
刷新路由器可以看到页面的更改
在src/actioins
目录下面创建one.js
文件,这里面将会定义数据操作类型与一些actions方法。
// actions/one.js
import 'whatwg-fetch';
export const UPDATE_ONE = 'update_one';
export function update(_data) {
return {
type: UPDATE_ONE,
data: _data
};
}
export function getone() {
return dispatch => {
fetch('http://v3.wufazhuce.com:8000/api/hp/bymonth/2016-09')
.then((response) => {
console.log(response)
})
};
}
这里我们需要安装fetch
来进行异步网络请求,当然你也可以使用其他网络请求工具。通过以下命令安装fetch
npm install whatwg-fetch --save
接口使用WeexOne项目里面的接口
redux-stack
这个生成器自动帮我们做好了reducer到store的绑定,所以我们只需要将注意力放在reducer中就可以了。
在src/reducers
目录下新建one.js
文件,这里我们将放置一些常用的数据操作。
// reducers/one.js
import { createReducer } from 'redux-create-reducer';
import { UPDATE_ONE } from '../actions/one';
const initialState = {};
export default createReducer(initialState, {
[UPDATE_ONE](state, data) {
return data.data;
}
});
并在reducers/index.js
文件中注册store
// reducersindex.js
......
import one from './one';
const rootReducer = combineReducers({
......
one,
......
});
export default rootReducer;
这里我们需要修改开始创建的Home.js
组件。
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as OneActions from '../actions/one';
class Home extends Component {
componentWillMount() {
this.props.getone() //发起action操作
}
render() {
return (
<div>
这是主页
</div>
)
}
}
/* 映射store中的state到组件中 */
function mapStateToProps(state) {
return {
one: state.one
};
}
/* 映射actions到组件中,并且注入dispatch方法 */
function mapDispatchToProps(dispatch) {
return bindActionCreators(OneActions, dispatch);
}
/* 修改组件导出方式,导出调用connect方法生成后的新组件*/
export default connect(mapStateToProps, mapDispatchToProps)(Home);
这里注入的state与actions都可以通过this.props
访问到。这时打开浏览器可以看到我们在one action
中的getone
方法打印出的异步请求数据
修改actions
当中的one.js
,在拿到数据后dispatch到reducer处理
// actions/one.js
import 'whatwg-fetch';
export const UPDATE_ONE = 'update_one';
export function update(_data) {
return {
type: UPDATE_ONE,
data: _data
};
}
export function getone() {
return dispatch => {
fetch('http://v3.wufazhuce.com:8000/api/hp/bymonth/2016-09').then((response) => {
console.log(response)
return response.json()
}).then((data) => {
/** 返回的json格式为
{
res: 0,
data: [...]
}
*/
dispatch(update(data.data[0]))
})
};
}
由于fetch
库提供Promise
的支持,所以可以使用then结构。
在redux开发工具中我们可以看到如下显示
在末尾处可以看到state
中的one已经有数据了,接下来我们将数据绑定到界面组件。
回到还是创建的Home.js
组件中,我们将需要的数据绑定到界面中
......
render() {
const { one } = this.props
return (
<div>
<h2>{one.hp_content}</h2>
<hr/>
<p>{one.hp_author}</p>
<img src={one.hp_img_url}></img>
</div>
)
}
......
这是浏览器里面的页面已经有数据了
经过一些简单的css样式调整得到的效果如下
这篇文章讲述了react搭配redux的基础用法,关于react-router
的部分本文没有详细讲解,但是react-router的难度也不大,上手也很快。如果需要使用webpack ensure
按需加载,需要将组建导出格式换成CommonJS
规范导出
module.exports = React.createClass({
render() {
<div>示例页面</div>
}
})
详细可以参考react-router示例程序