React+DvaJs实现简单的点餐系统demo
- 动态加载路由组件
- 路由守卫
- 二级路由,三级路由
- 展示注册和登录
- 表单校验
- 存储注册信息
- 登录验证
- 登录后的状态管理
- 隐藏登录和注册按钮
- 显示用户信息和退出
- 菜单页面的效果展示
- 展示菜单页面
- 购物车展示以及添加商品操作
- 添加购物车加减功能
- 计算总价以及解决重复添加购物类别的问题
- 添加新菜单类别组件
- 新菜单类别数据存取到接口中
- 从数据接口中删除菜单类别
操作步骤:
- 创建项目
$ dva new demo-name
- 进入并运行项目
$ cd demo-name
$ npm start
- 引入antd组件库
$ npm install antd --save
- 项目自带less,如果你习惯使用sass,可以进行自定义安装,安装sass
npm install node-sass sass-loader --save
- 按需加载
$ cnpm install babel-plugin-import --save-dev
在根目录.webpackrc文件,并在文件中添加插件配置,静态文件配置
const path = require('path');
export default {
//`babel-plugin-import --save` antd 按需加载webpack配置
extraBabelPlugins:[
['import',{ libraryName: 'antd', libraryDirectory: 'es', style: true }]
],
//引入静态文件配置路径
alias: {
Assets: path.resolve(__dirname,'./src/assets')
}
}
- webpack反向代理
在根目录.webpackrc文件
"proxy": {
"/api": {
"target": "http://jsonplaceholder.typicode.com/",
"changeOrigin": true,
"pathRewrite": { "^/api": "" }
}
}
访问 http://localhost:8000/api/users 如果你看见一串json数据代表代理成功,就可以进行下一步开发了(该json数据是dva官方提供的测试数据,使用Mockjs开发) 完成以上准备工作我们就开始正式的demo开发了
- reducer里面必须是纯函数,什么是纯函数?
- 一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。
dva相当于将很多的API集中到了一起,变为了更为统一的API。
import React from 'react';
import dva, { connect } from 'dva';
import { Router, Route } from 'dva/router'
const app = dva()
app
:统领所有API的载体,你会发现store和路由都是统一“绑在”app上的。 组件不是,组件仍然独立。
dva
将原来的Redux
中combineReducer
这个东西进行了一个拆分:
app.model({
namespace: 'count', //model的命名空间,同时也是他在全局 state 上的属性
state: 0, //初始值
reducers: { //用于处理同步操作,由 action 触发
add(state) { return state + 1 }
minus(state) { return state - 1 }
}
})
相当于将一个个的reducer
,原来可以用combineReducer
合并,现在可以用
app.model()
app.model()
app.model()
这样的形式来进行组织。
发送命令的时候,必须加上命名空间。
this.props.dispatch({'type':'count/add'})
dva
帮我们隐形的完成了dispatch
和props
的映射函数:
App = connect(({count}) =>{
return {
count:count
}
})(App)
在组件的内部任意时候都可以去进行一个action
的发送操作,不需要再注入constructor
中的props
:
this.props.dispatch({'type':'count/add'})
model
可以自由的交给任何一个组件去发送 action
去改变它。
app.start('#root')
put
:你就认为put
就等于 dispatch
就可以了;
call
:可以理解为实行一个异步函数,是阻塞型的,只有运行完后面的函数,才会继续往下;在这里可以片面的理解为async
中的await
!但写法直观多了!