结构-行为-样式 - React + Redux + Webpack + Antd 小Demo

react

最近在学习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

回到顶部