博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React框架Umi实战(2)整合dva开发后台管理系统
阅读量:6290 次
发布时间:2019-06-22

本文共 11392 字,大约阅读时间需要 37 分钟。

umi官方推荐结合dva使用更配哦,其实他们都是同一位开发者开发的,属于阿里内部开源框架。

1 修改.umirc.js,开启dva支持

// ref: https://umijs.org/config/export default {  plugins: [    // ref: https://umijs.org/plugin/umi-plugin-react.html    ['umi-plugin-react', {      antd: true,      dva: true,      dva: {          immer: true        },      dynamicImport: false,      title: 'umis',      dll: false,      hardSource: false,      routes: {        exclude: [          /components\//,        ],      },    }],  ],}复制代码

2 修改layouts

先搞一个后台的布局,可以参考ANT DESIGN PRO https://pro.ant.design/ layouts\index.js

import styles from './index.less';import { Layout, Menu, Breadcrumb, Icon } from 'antd';import { Component } from 'react';import Link from 'umi/link';import logo from '../assets/logo.svg';const {Header, Content, Footer, Sider} = Layout;const SubMenu = Menu.SubMenu;class BasicLayout extends Component {  constructor(props) {    super(props);    this.state = {      collapsed: false,    };  }  toggle = () => {  this.setState({    collapsed: !this.state.collapsed,  });}render(){return (    
logo

Ant Design Pro

Users
Team} >
Team 1
Team 2
{/*此处可加面包屑*/} { this.props.children }
Ant Design ©2018 Created by Ant UED
);}}export default BasicLayout;复制代码

layouts\index.less

.logo {  height: 64px;  position: relative;  line-height: 64px;  transition: all 0.3s;  background: #002140;  overflow: hidden;  img {    display: inline-block;    vertical-align: middle;    height: 32px;  }  h1 {    color: white;    display: inline-block;    vertical-align: middle;    font-size: 20px;    margin: 0 0 0 12px;    font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;    font-weight: 600;  }}.trigger {  font-size: 18px;  line-height: 64px;  padding: 0 24px;  cursor: pointer;  transition: color .3s;  .logo {  height: 32px;  background: rgba(255,255,255,.2);  margin: 16px;}}.sider {  min-height: 100vh;  box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);  position: relative;  z-index: 10;  &.ligth {    background-color: white;    .logo {      background: white;      h1 {        color: #002140;      }    }  }}复制代码

浏览器访问你会看到如下效果:

3 改造users页面,完成dva整个流程。

  • 在pages下创建users目录
  • 创建index.js 会生成默认路由http://localhost:8000/users
import { connect } from 'dva';import { Table, Pagination, Popconfirm } from 'antd';import styles from './users.css';const PAGE_SIZE = 5;function Users({ list: dataSource, total, page: current }) {  function deleteHandler(id) {    console.warn(`TODO: ${id}`);  }  const columns = [    {      title: 'Name',      dataIndex: 'name',      key: 'name',      render: text => {text},    },    {      title: 'Email',      dataIndex: 'email',      key: 'email',    },    {      title: 'Website',      dataIndex: 'website',      key: 'website',    },    {      title: 'Operation',      key: 'operation',      render: (text, { id }) => (                  Edit          
Delete
), }, ]; return (
record.id} pagination={
false} /> );}function mapStateToProps(state) { const { list, total, page } = state.users; console.log(state.test); return { list, total, page, };}export default connect(mapStateToProps)(Users);复制代码
  • 创建对应的model.js,因为只有一个model所以不需要创建models目录。但是名字必须为model.js,不然不能自动注册。
//只有一个model的话,可以不用建models目录。但名字必须为model。jsimport * as usersService from './service';export default {  namespace: 'users',  state: {    list: [],    total: null,  },  reducers: {    save(state, { payload: { data: list, total } }) {      return { ...state, list, total };    },  },  effects: {    *fetch({ payload: { page } }, { call, put }) {      const { data} = yield call(usersService.fetch, { page });      yield put({ type: 'save', payload: { data, total: data.length } });    },  },  subscriptions: {    setup({ dispatch, history }) {      return history.listen(({ pathname, query }) => {        if (pathname === '/users') {          dispatch({ type: 'fetch', payload: query });        }      });    },  },};复制代码
  • 创建service.js 这个不需要约定名称,你随便起名字
import request from '../../utils/request';export function fetch({ page = 1 }) {  return request(`/api/users?_page=${page}&_limit=5`);}复制代码
  • 创建utils目录,封装统一请求api utils\request.js
import fetch from 'dva/fetch';function checkStatus(response) {  if (response.status >= 200 && response.status < 300) {    return response;  }  const error = new Error(response.statusText);  error.response = response;  throw error;}/** * Requests a URL, returning a promise. * * @param  {string} url       The URL we want to request * @param  {object} [options] The options we want to pass to "fetch" * @return {object}           An object containing either "data" or "err" */export default async function request(url, options) {  const response = await fetch(url, options);  checkStatus(response);  const data = await response.json();  const ret = {    data  };  return ret;}复制代码
  • 创建mock假数据 mock\user.js
export default {  '/api/users': [  {    "id": 1,    "name": "Leanne Graham",    "username": "Bret",    "email": "Sincere@april.biz",    "address": {      "street": "Kulas Light",      "suite": "Apt. 556",      "city": "Gwenborough",      "zipcode": "92998-3874",      "geo": {        "lat": "-37.3159",        "lng": "81.1496"      }    },    "phone": "1-770-736-8031 x56442",    "website": "hildegard.org",    "company": {      "name": "Romaguera-Crona",      "catchPhrase": "Multi-layered client-server neural-net",      "bs": "harness real-time e-markets"    }  },  {    "id": 2,    "name": "Ervin Howell",    "username": "Antonette",    "email": "Shanna@melissa.tv",    "address": {      "street": "Victor Plains",      "suite": "Suite 879",      "city": "Wisokyburgh",      "zipcode": "90566-7771",      "geo": {        "lat": "-43.9509",        "lng": "-34.4618"      }    },    "phone": "010-692-6593 x09125",    "website": "anastasia.net",    "company": {      "name": "Deckow-Crist",      "catchPhrase": "Proactive didactic contingency",      "bs": "synergize scalable supply-chains"    }  },  {    "id": 3,    "name": "Clementine Bauch",    "username": "Samantha",    "email": "Nathan@yesenia.net",    "address": {      "street": "Douglas Extension",      "suite": "Suite 847",      "city": "McKenziehaven",      "zipcode": "59590-4157",      "geo": {        "lat": "-68.6102",        "lng": "-47.0653"      }    },    "phone": "1-463-123-4447",    "website": "ramiro.info",    "company": {      "name": "Romaguera-Jacobson",      "catchPhrase": "Face to face bifurcated interface",      "bs": "e-enable strategic applications"    }  },  {    "id": 4,    "name": "Patricia Lebsack",    "username": "Karianne",    "email": "Julianne.OConner@kory.org",    "address": {      "street": "Hoeger Mall",      "suite": "Apt. 692",      "city": "South Elvis",      "zipcode": "53919-4257",      "geo": {        "lat": "29.4572",        "lng": "-164.2990"      }    },    "phone": "493-170-9623 x156",    "website": "kale.biz",    "company": {      "name": "Robel-Corkery",      "catchPhrase": "Multi-tiered zero tolerance productivity",      "bs": "transition cutting-edge web services"    }  },  {    "id": 5,    "name": "Chelsey Dietrich",    "username": "Kamren",    "email": "Lucio_Hettinger@annie.ca",    "address": {      "street": "Skiles Walks",      "suite": "Suite 351",      "city": "Roscoeview",      "zipcode": "33263",      "geo": {        "lat": "-31.8129",        "lng": "62.5342"      }    },    "phone": "(254)954-1289",    "website": "demarco.info",    "company": {      "name": "Keebler LLC",      "catchPhrase": "User-centric fault-tolerant solution",      "bs": "revolutionize end-to-end systems"    }  },  {    "id": 6,    "name": "Mrs. Dennis Schulist",    "username": "Leopoldo_Corkery",    "email": "Karley_Dach@jasper.info",    "address": {      "street": "Norberto Crossing",      "suite": "Apt. 950",      "city": "South Christy",      "zipcode": "23505-1337",      "geo": {        "lat": "-71.4197",        "lng": "71.7478"      }    },    "phone": "1-477-935-8478 x6430",    "website": "ola.org",    "company": {      "name": "Considine-Lockman",      "catchPhrase": "Synchronised bottom-line interface",      "bs": "e-enable innovative applications"    }  },  {    "id": 7,    "name": "Kurtis Weissnat",    "username": "Elwyn.Skiles",    "email": "Telly.Hoeger@billy.biz",    "address": {      "street": "Rex Trail",      "suite": "Suite 280",      "city": "Howemouth",      "zipcode": "58804-1099",      "geo": {        "lat": "24.8918",        "lng": "21.8984"      }    },    "phone": "210.067.6132",    "website": "elvis.io",    "company": {      "name": "Johns Group",      "catchPhrase": "Configurable multimedia task-force",      "bs": "generate enterprise e-tailers"    }  },  {    "id": 8,    "name": "Nicholas Runolfsdottir V",    "username": "Maxime_Nienow",    "email": "Sherwood@rosamond.me",    "address": {      "street": "Ellsworth Summit",      "suite": "Suite 729",      "city": "Aliyaview",      "zipcode": "45169",      "geo": {        "lat": "-14.3990",        "lng": "-120.7677"      }    },    "phone": "586.493.6943 x140",    "website": "jacynthe.com",    "company": {      "name": "Abernathy Group",      "catchPhrase": "Implemented secondary concept",      "bs": "e-enable extensible e-tailers"    }  },  {    "id": 9,    "name": "Glenna Reichert",    "username": "Delphine",    "email": "Chaim_McDermott@dana.io",    "address": {      "street": "Dayna Park",      "suite": "Suite 449",      "city": "Bartholomebury",      "zipcode": "76495-3109",      "geo": {        "lat": "24.6463",        "lng": "-168.8889"      }    },    "phone": "(775)976-6794 x41206",    "website": "conrad.com",    "company": {      "name": "Yost and Sons",      "catchPhrase": "Switchable contextually-based project",      "bs": "aggregate real-time technologies"    }  },  {    "id": 10,    "name": "Clementina DuBuque",    "username": "Moriah.Stanton",    "email": "Rey.Padberg@karina.biz",    "address": {      "street": "Kattie Turnpike",      "suite": "Suite 198",      "city": "Lebsackbury",      "zipcode": "31428-2261",      "geo": {        "lat": "-38.2386",        "lng": "57.2232"      }    },    "phone": "024-648-3804",    "website": "ambrose.net",    "company": {      "name": "Hoeger LLC",      "catchPhrase": "Centralized empowering task-force",      "bs": "target end-to-end models"    }  }],}复制代码

访问http://localhost:8000/users

4 总结

  • 按umi推荐的方式去创建目录
  • 注意约定名 pages目录下的所有js都回被默认生成路由,可通过配置排出
  • 省略了model的手动注册,至于忽略namespace,我试了不行
  • 各个page的model不能相互引用?不是很明白什么意思,我试了每个page都能获取所有的state,并不是只能获取属于自己的。可能是我理解有误。
  • 没有看出来umi的好处,只是目录的区别吗? 这个 issues 下有关于umi按page分的讨论。https://github.com/sorrycc/blog/issues/66 希望知道umi核心优势的小伙伴留言解释下,前端菜鸟不是很懂。

别忘了关注我 mike啥都想搞

还有其他后端技术分享在我的公众号。

转载于:https://juejin.im/post/5c7fc43951882549664b09f2

你可能感兴趣的文章
PHP导出table为xls出现乱码解决方法
查看>>
PHP问题 —— 丢失SESSION
查看>>
Java中Object类的equals()和hashCode()方法深入解析
查看>>
数据库
查看>>
Vue------第二天(计算属性、侦听器、绑定Class、绑定Style)
查看>>
dojo.mixin(混合进)、dojo.extend、dojo.declare
查看>>
Python 数据类型
查看>>
iOS--环信集成并修改头像和昵称(需要自己的服务器)
查看>>
PHP版微信权限验证配置,音频文件下载,FFmpeg转码,上传OSS和删除转存服务器本地文件...
查看>>
教程前言 - 回归宣言
查看>>
PHP 7.1是否支持操作符重载?
查看>>
Vue.js 中v-for和v-if一起使用,来判断select中的option为选中项
查看>>
Java中AES加密解密以及签名校验
查看>>
定义内部类 继承 AsyncTask 来实现异步网络请求
查看>>
VC中怎么读取.txt文件
查看>>
如何清理mac系统垃圾
查看>>
企业中最佳虚拟机软件应用程序—Parallels Deskto
查看>>
Nginx配置文件详细说明
查看>>
怎么用Navicat Premium图标编辑器创建表
查看>>
Spring配置文件(2)配置方式
查看>>