先介绍一个umi,阿里开源的一个企业级可插拔的react脚手架,
umi相对比react官方推荐的脚手架更加的简单,更贴近vue-cli的使用感受,而本文仅仅介绍基础使用方法,高手请绕行
开发展示仿叮咚买菜后台管理系统预览: http://dingdong-admin.nodebook.top/
仿叮咚买菜 前台页面: http://dingdong.nodebook.top/
叮咚买菜后台管理系源码: https://github.com/cgq001/dingdong-admin
叮咚买菜源码: https://github.com/cgq001/dingdong
功能说明:
演示动图:
介绍内容来自官网,感兴趣可 百度 umi 到官网查看详情
创建项目: yarn create umi
选择 project
? Select the boilerplate type (Use arrow keys)
ant-design-pro - Create project with an layout-only ant-design-pro boilerplate, use together with umi block.
❯ app - Create project with a simple boilerplate, support typescript.
block - Create a umi block.
library - Create a library with umi.
plugin - Create a umi plugin.
然后,选择你需要的功能 这里 antd 是UI库 dva 封装了redux 等
? What functionality do you want to enable? (Press to select, to toggle all, to invert selection)
❯◯ antd
❯◯ dva
◯ code splitting
◯ dll
运行项目
yarn start
目录
├── dist/ // 默认的 build 输出目录
├── mock/ // mock 文件所在目录,基于 express
├── config/
├── config.js // umi 配置,同 .umirc.js,二选一
└── src/ // 源码目录,可选
├── layouts/index.js // 全局布局
├── pages/ // 页面目录,里面的文件即路由
├── .umi/ // dev 临时目录,需添加到 .gitignore
├── .umi-production/ // build 临时目录,会自动删除
├── document.ejs // HTML 模板
├── 404.js // 404 页面
├── page1.js // 页面 1,任意命名,导出 react 组件
├── page1.test.js // 用例文件,umi test 会匹配所有 .test.js 和 .e2e.js 结尾的文件
└── page2.js // 页面 2,任意命名
├── global.css // 约定的全局样式文件,自动引入,也可以用 global.less
├── global.js // 可以在这里加入 polyfill
├── app.js // 运行时配置文件
├── .umirc.js // umi 配置,同 config/config.js,二选一
├── .env // 环境变量
└── package.json
使用
一.路由
1.1关于.umirc.js 文件配置
umi 可以使用类似 nuxt.js的约定式路由,当然本次介绍 类似于我们常在vue用使用的配置式路由,即可在这里配置
具体配置详情,请看 代码注释:
export default {
treeShaking: true,
routes: [ // 配置路由
{ path: '/', //重定向到主页
redirect: '/index/'
},
{
path: '/index', //主页
component: '../layouts/index', //公共主页
// Routes: ['./routes/Login.js'] , //这里是相对根目录(非pages)的,文件名后缀不能少
routes: [
// { path: '/index/', component: '../pages/index' },
{ path: '/index/', component: '../pages/Home/HomeIndex/HomeIndex' }, //首页
{ path: '/index/data/index', component: '../pages/Datas/DataIndex/DataIndex' ,srcPath: '12456'} , //数据分析
{ path: '/index/product/shoping/index', component: '../pages/Product/Shoping/ShopIndex/ShopIndex' }, //商品管理
{ path: '/index/product/shoping/add', component: '../pages/Product/Shoping/AddShop/AddShop' }, //添加商品
{ path: '/index/product/class/index', component: '../pages/Product/Class/ClassIndex/ClassIndex' }, //分类管理
{ path: '/index/product/class/add', component: '../pages/Product/Class/AddClass/AddClass' }, //添加分类
{ path: '/index/product/comment/index', component: '../pages/Product/Comment/CommentIndex/CommentIndex' }, //评论管理
{ path: '/index/set/personalcenter/index', component: '../pages/Set/PersonalCenter/PersonalCenter' }, //个人中心
{ path: '/index/set/PersonalSettings/index', component: '../pages/Set/PersonalSettings/PersonalSettings' }, //个人设置
{ path: '/index/order/refund/index', component: '../pages/Order/Refund/RefundIndex/RefundIndex'} , //待退款列表
{ path: '/index/order/refund/details', component: '../pages/Order/Refund/RefundDetails/RefundDetails'}, //退款详情
{ path: '/index/order/shipped/index', component: '../pages/Order/Shipped/ShippedIndex/ShippedIndex'} , //待发货详情
{ path: '/index/order/shipped/deliver', component: '../pages/Order/Shipped/ShippedDeliver/ShippedDeliver'} , //待发货详情
{ path: '/index/control/carousel/index', component: '../pages/Control/Carousel/CarouselIndex/CarouselIndex'} , //布局控制 首页轮播 轮播列表
{ path: '/index/control/carousel/add', component: '../pages/Control/Carousel/CarouselAdd/CarouselAdd'} , //布局控制 首页轮播 添加轮播图
{ path: '/index/control/keyword/index', component: '../pages/Control/Keyword/KeywordIndex/KeywordIndex'} , //布局控制 搜索发现关键词 关键词列表
{ path: '/index/marketing/buy/index', component: '../pages/Marketing/Buy/BuyIndex/BuyIndex'}, //营销控制 首页疯狂抢购 疯狂抢购列表
{ path: '/index/marketing/buy/add', component: '../pages/Marketing/Buy/BuyAdd/BuyAdd'} //营销控制 首页疯狂抢购 所有商品列表
]
},
{
path: '/login', //登录页
component: './Login/Login',
}
],
plugins: [
// ref: https://umijs.org/plugin/umi-plugin-react.html
['umi-plugin-react', {
antd: true, //开启antd UI库
dva: true, //开启dav
dynamicImport: false,
title: '商城管理系统', //title
dll: false,
routes: {
exclude: [
/models\//,
/services\//,
/model\.(t|j)sx?$/,
/service\.(t|j)sx?$/,
/components\//,
],
},
}],
],
"proxy": { //请求代理
"/api": {
"target": "http://192.168.188.200:5005/", //http://192.168.188.200:5005/admin/
"changeOrigin": true,
"pathRewrite": { "^/api" : "" }
}
}
}
1.2关于页面内的路由跳转
//引入
import Link from 'umi/link';
import withRouter from 'umi/withRouter';
//使用
数据分析
// 最后 生成的 包含Link 的组件 需要子withRouter(组件) 中高阶一下即可
1.3导航守卫
在 .umirc.js 文件中声明的路由中配置: Routes: [’./routes/Login.js’]
然后在 routes/Login.js中进行路由守卫
//例如
path: '/index', //主页
component: '../layouts/index',
Routes: ['./routes/Login.js'] , //这里是相对根目录(非pages)的,文件名后缀不能少
Login.js
export default props => {
if(Math.random > 0.5){ // 大于0.5 去 login 否则去访问的这个路径页面,从而完成导航守卫
return
}
return (
{props.children}
)
}
二.dva
2.1在models/UserRedux.js 文件 存储全局状态
// 获取 本地存储的 token
let token = localStorage.getItem('token') || sessionStorage.getItem('token')
let global ={
namespace: 'UserRedux', //model的命名空间,区分多个model
state : {
https: 'http://192.168.188.200:5005/', //普通接口
httpsUpload: 'http://192.168.188.200:5005/index/upload', //图片上传接口
token: token || null, //token
isLogin: false , //是否正在登录
userList:{
name: '张三'
}
},
effects:{ // 异步操作
},
reducers: { //更新状态(同步)
isLogin(state,action){
let stateSrc = state
stateSrc.isLogin = true
return stateSrc
},
removeLogin(state,action){
let stateSrc = state
stateSrc.isLogin = false
return stateSrc
},
setToken(state,action){ //设置token
let stateSrc = state
stateSrc.token = action.token
return stateSrc
},
setUserList(state,action){ //设置用户信息
let stateSrc = state
stateSrc.userList = action.userList
return stateSrc
}
}
}
export default global;
2.2使用全局状态
import { connect } from 'dva' //引入dva
export default connect(
state => ({
loading: state.loading , //dva已经可以获得 loading状态
UserRedux: state.UserRedux //获取指定命名空间的模型状态
}),
{
setUserList: userList => ({
type: 'UserRedux/setUserList', //action的type需要以命名空间为前缀+reducer名称
userList //拿到 userList
})
}
)(withRouter(Headers))
this.props.UserRedux.token //即可获取 UserRedux中的内容
//Headers为基本组件 withRouter为路由告诫组件, withRouter(Headers) 需要使用Link跳转页面的写法