结构-行为-样式 - React + Redux + Webpack + Antd 小Demo
最近在学习React,从小白到入门,谈不上精通。每一个新的框架都是一样,主要是自己有自己的学习方法,再多的框架也是手到擒来。React主要的思想就是组件开发,官网上的Demo也说的很详细,就是让你在做一个页面之前,先想想,这个东西能拆分成什么模块,子模块,怎样嵌套。设计的思路理清楚之后才是动手写代码,同时,作为一个框架,它采取的是一种包容的态度。一个Demo下来,除了官方的那几个Js之外,其他大部分都是第三方的插件。Redux就是Flux的改编版本。不费话了,来看看我的这个Demo吧:
首先,咱们来看下整体目录结构:
一、先看看最终的样子:
其实就是套用了Antd的一个布局架子,加上表格和自定义的搜索栏,基本上实现了增删改查的功能。这个页面包括搜索模块与表格模块,这里咱们只说表格模块,搜索模块类似。
二、第一层,也就是整个页面的外层,调用 的是Antd的布局代码(布局 Layout - Ant Design):
import React from 'react';import NavLink from './NavLink';
import { Layout, Menu, Breadcrumb, Icon } from 'antd';
const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;
export default React.createClass({
render(){
return(
<Layout>
<Header className="header">
<div className="logo" >
<img src={require("../images/logo.png")} alt="" width="112" height="35" />
</div>
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['3']}
style={{ lineHeight: '64px' }}
className="headerMenu"
>
<Menu.Item key="1"><NavLink to="/" >首页</NavLink></Menu.Item>
<Menu.Item key="2"><NavLink to="/about">报表</NavLink></Menu.Item>
<Menu.Item key="3"><NavLink to="/repos/pageb" onlyActiveOnIndex>配置</NavLink></Menu.Item>
</Menu>
</Header>
<Layout>
<Sider width={200} style={{ background: '#BD2626' }}>
<Menu
mode="inline"
theme="dark"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }} className="diy-dark"
>
<SubMenu key="sub1" title={<span><Icon type="user" />权限管理</span>}>
<Menu.Item key="1"><NavLink to="/repos/pagea">组织架构</NavLink></Menu.Item>
<Menu.Item key="2"><NavLink to="/repos/pageb">用户管理</NavLink></Menu.Item>
<Menu.Item key="3">角色管理</Menu.Item>
</SubMenu>
<SubMenu key="sub2" title={<span><Icon type="laptop" />参数配置</span>}>
<Menu.Item key="5">功能配置</Menu.Item>
<Menu.Item key="6">业态配置</Menu.Item>
<Menu.Item key="6">特征配置</Menu.Item>
<Menu.Item key="6">码表配置</Menu.Item>
</SubMenu>
<SubMenu key="sub3" title={<span><Icon type="notification" />日志管理</span>}>
<Menu.Item key="9">接口日志</Menu.Item>
<Menu.Item key="10">操作日志</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '12px 0' }}>
<Breadcrumb.Item>配置</Breadcrumb.Item>
<Breadcrumb.Item>权限管理</Breadcrumb.Item>
<Breadcrumb.Item>组织架构</Breadcrumb.Item>
</Breadcrumb>
<Content style={{ background: '#fff', padding: 15, margin: 0, minHeight: 515 }}>
{this.props.children}
</Content>
</Layout>
</Layout>
</Layout>
)}
});
注:整个Js看作是一个组件,子组件中Content下面。
三、第2-1层,表格组件:
3.1、首先,定义两个自定义事件,删除与修改:
//删除一条记录handleDelete(record){
this.props.dispatch(action.doDelete({record,data}));
}
//修改一条记录
handleModify (record) {
record.title = "修改记录";
record.modalType = "modify";
let isVisible = true;
this.props.dispatch(action.setVisible(isVisible));
let current = record;
this.props.dispatch(action.showModal({current,data}));
}
3.2、然后在构造函数中绑定我们的自定义事件,得到当前对象:
//构造函数constructor(props) {
super(props);
this.handleDelete = this.handleDelete.bind(this);
this.handleModify = this.handleModify.bind(this);
}
3.3、调用Antd的表格组件,进行表格的组装,事件在columns时就可以先设定好,具体如下:
const columns = [{title: '姓名',
dataIndex: 'name',
key: 'name',
render: text => <a href="javascript:;">{text}</a>,
}, {
title: '邮箱',
dataIndex: 'email',
key: 'email',
}, {
title: '手机',
dataIndex: 'phone',
key: 'phone',
},{
title: '地址',
dataIndex: 'address',
key: 'address',
}, {
title: '操作',
key: 'action',
render: (text, record) => (
<span>
<a href="javascript:;" onClick={()=>this.handleModify(record)} >修改</a>
<span className="ant-divider" />
<a href="javascript:;" onClick={()=>this.handleDelete(record)} >删除</a>
</span>
),
}];
3.4、最后Render出来的虚拟Dom就一行:
return (<Table columns={columns} dataSource={data} />
);
四、事件处理与状态传递(Redux相关):
4.1、Redux工作原理(盗图一张):
那些很专业的话就不说了,这里就说实际Demo中的对应关系。实际开发中,应该要定义Action、Reducer、Store三个文件,它们工作流程就是上面图中所示。
4.2、表格相关 Action:
//修改记录export const doModify = ({current,data})=>{
for(let i=0;i<data.length;i++){
if(current.key == data[i].key){
data[i] = current;
data[i].address = current.residence.join(" - ");
break;
}
}
const list = data;
return {
type:'DO_MODIFY',
list
}
}
//删除记录
export const doDelete = ({record,data})=>{
for(let i=0;i<data.length;i++){
if(data[i].key == record.key){
data.splice(i,1);
break;
}
}
let list = data;
return {
type:'DO_DELETE',
list
}
}
注:应该把当前动作所包含的逻辑写在Action中,不要写在Reducer中。触发Action的地方应该是在组件的文件中,通过dispatch方法来触发 :this.props.dispatch(action.showModal({current,data})); 类似这个。
4.3、增删改查的 Reducer:
const doHeader = (state='',action)=>{switch(action.type){
case 'DO_SUBMIT':
return {"list":action.list};
case 'DO_ADD':
return {"list":action.list};
case 'DO_MODIFY':
return {"list":action.list};
case 'DO_DELETE':
return {"list":action.list};
default:
return state;
}
}
注:建议把一个组件的Reducer放在一起,最终Store调用 的就是一个总的Reducer。
4.4、只有一个Store:
import {createStore} from 'redux';import todoApp from '../reducers';
let store = createStore(
todoApp
);
export default store;
注:这里的todoApp就是Reducers的总入口。
所以,最终的思路就是,在组件的文件中,有一个事件,通过 dispatch 分发到Action,处理完之后通过Reducer反映到全局的State中,直接的就是另一个组件监听到它需要 的State改变了,反映到页面。整个过程都是单向的,一个组件中的Props值是不可以改变的。
五、webpack配置:
5.1、开发模式和发布模式:
5.1.1、开发模式会定义devserver和热更新,具体如下:
devServer: {//webpack-dev-server 配置contentBase: "./server",//本地服务器所加载的页面所在的目录
port: 8888,
colors: true,//终端中输出结果为彩色
historyApiFallback: true,//不跳转
inline: true,
hot:true//热更新
},
postcss:[
autoprefixer({browsers:['last 10 versions']})//postcss 插件
],
plugins:[
new webpack.BannerPlugin('Copyright Chvin'),//添加 js头
new webpack.HotModuleReplacementPlugin()//热更新
]
5.1.2、发布模式则不用那么麻烦,定义一下文件导出格式与入口文件:
plugins: [new HtmlWebpackPlugin({
template: __dirname + "/server/index.tmpl.html"
}),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("[name]-[hash].css"),
new webpack.optimize.DedupePlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV':'"production"'
})
],
注:这里省略了其他配置,只是写出了要注意的地方
5.2、打包与调试命令配置(在Package.json中),start是本地开发命令,build就是发布文件生成:
"scripts": {"start": "webpack-dev-server --progress && echo sddss",
"build": "webpack --config ./webpack.production.config.js --progress"
},
六、路由配置:
6.1、引用路由:
import { Router, Route, hashHistory, IndexRoute } from 'react-router';
6.2、首页、嵌套。Router中包含Route,首页的路由可以通过IndexRoute来定义,同时,要定义路由中对应的组件。具体如下:
render(<Provider store={store} >
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="/repos" >
<Route path="/repos/pagea" component={About}/>
<Route path="/repos/pageb" component={Counter}/>
</Route>
<Route path="/about" component={About}/>
</Route>
</Router>
</Provider>
,document.getElementById('root'));
完整Demo下载:https://github.com/chickentang/GIT_TANG
有写的不对的地方欢迎留言。。。
以上是 结构-行为-样式 - React + Redux + Webpack + Antd 小Demo 的全部内容, 来源链接: utcz.com/z/382311.html