下载插件dva和history

  • 由于dva的路由有问题,所以引入history模块进行路由操作
  • 基础配置
  • index.js
    1. import dva from 'dva'
    2. //引入history
    3. import {createBrowserHistory} from 'history'
    4. //引入路由配置
    5. import router from 'router'
    6. //实例化dva
    7. const app = dva({history:createBrowserHistory()})
    8. //挂载路由
    9. app.router(router)
    10. //挂载节点
    11. app.start('#root')

router路由设置

  • index.js ```javascript import React from ‘react’; import RouterMap from ‘./map’ import Routes from ‘./routes’

function RouterView(props) { const routes = props.routes ? props.routes : Routes; return } export default RouterView;

  1. - routes.js ---路由表
  2. ```javascript
  3. import Index from '../containers/Index'
  4. import Login from '../containers/Login'
  5. export default [{
  6. path: '/index',
  7. name: 'index',
  8. component: Index,
  9. token: true,
  10. }, {
  11. path: '/login',
  12. name: 'login',
  13. component: Login
  14. },]
  • map.js—渲染路由 ```javascript

import React, { Component } from ‘react’; //引入dva/router的路由组件 import { Router, Route, Switch, Redirect } from “dva/router”;

class RouterMap extends Component { render() { const { routes, history } = this.props; const defaultRoute = return { routes.map((item) => { //有children就等于否则等于【】 const children = item.children === undefined ? [] : item.children const Comp = item.component; //判断是否需要token鉴权 if (item.token) { if (!localStorage.getItem(‘token’)) { return } }

  1. return <Route key={item.name + 'route'} path={item.path}
  2. component={() => {
  3. return <Comp routes={children} history={history}></Comp>
  4. }} />
  5. }).concat([defaultRoute])
  6. }
  7. </Switch>
  8. </Router>
  9. }

} export default RouterMap;

  1. <a name="EtKBz"></a>
  2. ### dva路由传参
  3. ```javascript
  4. //state传参
  5. this.props.history.push('/index/productDetail', {
  6. pid: text.pid
  7. })
  8. //接收参数
  9. this.props.location.state.pid
  10. 由于组件没有location我们需要使用装饰器来给组件添加方法
  11. import { withRouter } from 'dva/router'
  12. @withRouter
  13. class productDetail extends Component {
  14. render() {
  15. return <></>
  16. }
  17. }

不会配置装饰器可参考https://www.yuque.com/docs/share/c4c1479e-114c-4b17-ab70-65748a3db54b?# 《在dva使用装饰器》

dva的仓库

namespace

model 的命名空间,同时也是他在全局 state 上的属性,只能用字符串,不支持通过 . 的方式创建多层命名空间。

state

初始值,优先级低于传给 dva()opts.initialState

reducers

以 key/value 格式定义 reducer。用于处理同步操作,唯一可以修改 state 的地方。由 action 触发。
格式为 (state, action) => newState[(state, action) => newState, enhancer]
详见: https://github.com/dvajs/dva/blob/master/packages/dva-core/test/reducers.test.js

effects

以 key/value 格式定义 effect。用于处理异步操作和业务逻辑,不直接修改 state。由 action 触发,可以触发 action,可以和服务器交互,可以获取全局 state 的数据等等。
格式为 *(action, effects) => void[*(action, effects) => void, { type }]

subscriptions

以 key/value 格式定义 subscription。subscription 是订阅,用于订阅一个数据源,然后根据需要 dispatch 相应的 action。在 app.start() 时被执行,数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。
格式为 ({ dispatch, history }, done) => unlistenFunction

为了方便使用,我们封装一下store

  • 目录结构

    1. store-
    2. |-index.js //加载model
    3. |-model文件夹
    4. -| user.js//用户仓库
    5. -| home.js//首页仓库
  • index.js -加载所有仓库 ```javascript const context = require.context(‘./model’, false, /.js$/); //通过context.keys()获取model目录下面的文件名

//遍历文件名,获取文件内容,返回个数组 const getModel = context.keys().map(key => context(key));

export const createModel = function (app) { //遍历获取到的model数组集合,分别将每一个model绑定到 app.model() return getModel.map(model => app.model(model.default)) }

  1. - model文件夹-存放仓库
  2. - user.js-用户仓库
  3. ```javascript
  4. import { _getUserByToken } from '@/api/user'
  5. //axios请求数据
  6. export default {
  7. //命名空间
  8. namespace: 'user',
  9. //初始值
  10. state: { token: '',uid:'' },
  11. //唯一可以修改state的地方
  12. reducers: {
  13. TOKEN(state, { payload }) {
  14. // 保存数据到 state
  15. return { ...state, token: payload };
  16. },
  17. UID(stata,{payload}){
  18. return { ...state, uid:payload };
  19. }
  20. },
  21. //处理异步的state数据
  22. effects: {
  23. *getuser({ token }, { put, call }) {
  24. let res = yield call(_getUserByToken, token);
  25. //判断code为1改变uid
  26. if (res.code) {
  27. yield put({ type: 'UID', payload: res.uid });
  28. }
  29. }
  30. }
  31. }