美文网首页dva相关知识我学 dva 那些事儿nodejs
dva 2.0中如何使用代码进行路由跳转

dva 2.0中如何使用代码进行路由跳转

作者: dkvirus | 来源:发表于2017-12-06 15:45 被阅读4502次

概述

在上篇 dva router4.0 使用实践总结 中主要介绍了 dva 中使用 react-router@4.0 标签写法控制路由。如下:

        <Switch>
          <Route path="/" exact render={() => (<Redirect to="/dashboard" />)} />
          {
            routes.map(({ path, ...dynamics }, key) => (
              <Route
                exact
                key={key}
                path={path}
                component={dynamic({ app, ...dynamics })}
              />
            ))
          }
          <Route component={error} />
        </Switch>

但是实际开发中,我们可能会需要在代码中进行路由的跳转。本文主要介绍在 dva 中使用代码进行路由跳转以及参数传递。

理清关系

dva 升级到 2.0 版本以后,也将内部使用的 dva/router 从 react-router@3.0 升级到了 react-router@4.0。react-router@4.0 文档 API

react-router@4.0 让路由变得更简单,最大特点就是可以路由嵌套,可是如果照搬使用 react-router@4.0 的写法,你会发现在 dva 中是行不通的,查看 dva/router 的源码可以看到:

// dva/router.js
module.exports = require('react-router-dom');
module.exports.routerRedux = require('react-router-redux');

其中第一行导出的react-router-dom就是 react-router@4.0 文件,第二行导出的react-router-redux是 react-router 配合 redux 使用的中间库。因为 dva 中使用到了 redux,所以我们在配置的时候还需要注意到这一点。

由于 dva 将react-router-domreact-router-redux都封装到了 dva/router 中,在使用 react-router@4.0 和 redux 里面的东西时只需引入 dva/router 这个包即可。

路由跳转

引入 dva/router,使用 routerReux 对象的 push 方法控制,值为要跳转的路由地址,与根目录下 router.js 中配置的路由地址是相同的。routerReux 就是上面 dva/router 第二个导出的 react-router-redux 包对象。

此处示例为跳转到 /user 路由。

// models > app.js
import { routerRedux } from 'dva/router';

export default {
  // ...
  effects: {
      // 路由跳转
      * redirect ({ payload }, { put }) {
        yield put(routerRedux.push('/user'));
      },
  }
  // ...
}

携带参数

有时路由的跳转还需要携带参数。

传参:

routerRedux.push 方法的第二个参数填写参数对象。此处示例表示跳转到 /user 路由,并携带参数 {name: 'dkvirus', age: 20}

// models > app.js
import { routerRedux } from 'dva/router';

export default {
  // ...
  effects: {
      // 路由跳转
      * redirect ({ payload }, { put }) {
        yield put(routerRedux.push('/user', {name: 'dkvirus', age: 20}));
      },
  }
  // ...
}

接收参数:

// models > user.js
export default {
  subscriptions: {
    /**
     * 监听浏览器地址,当跳转到 /user 时进入该方法
     * @param dispatch 触发器,用于触发 effects 中的 query 方法
     * @param history 浏览器历史记录,主要用到它的 location 属性以获取地址栏地址
     */
    setup ({ dispatch, history }) {
      history.listen((location) => {
        console.log('location is: %o', location);
        console.log('重定向接收参数:%o', location.state)
        // 调用 effects 属性中的 query 方法,并将 location.state 作为参数传递 
        dispatch({
          type: 'query',
          payload: location.state,
        })
      });
    },
  },
  effects: {
    *query ({ payload }, { call, put }) {
       console.log('payload is: %o', payload);
    }
  }
  // ...
}

在 user.js 中 subscriptions 属性会监听路由。当 app.js 中通过代码跳转到 /user 路由,models>user.js>subscriptions 属性中的 setup 方法会被触发,location 记录着相关信息。打印如下。

location is: Object
    hash: ""
    key: "kss7as"
    pathname: "/user"
    search: ""
    state: {name: "bob", age: 21}
重定向接收参数:Object
    age:21
    name:"bob"

可以看到 location.state 就是传递过来的参数。在 subscriptions 中可以使用 dispatch 触发 effects 中的方法同时传递参数。

需要注意的事,在 dva@1.* 版本中,要获取对象还要用 location.query 对象,而到了 dva@2.* 就变成了 location.state 对象。

相关文章

网友评论

  • 9f385e0b7ab4:您好。有一个关于二级路由的问题想请教您,怎么将二级路由和model关联在一起。及按需加载。
    dkvirus:官方提供的示例 [动态加载model](https://dvajs.com/guide/develop-complex-spa.html#%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BDmodel),不知道是不是你需要的。
  • 悦者生存:大神,问你个问题浏览器直接访问嵌套路由报错,你遇到过么
    dkvirus:@悦者生存 https://github.com/dkvirus/dva/issues 你可以在这上面开个 issue,贴点关于你路由那块代码,我看看。
    悦者生存:@dkvirus Uncaught SyntaxError: Unexpected token < index.js:1
    我都是按照dva框架默认的生成搭建的react-router4,但是不能在浏览器直接访问嵌套路由
    dkvirus:@悦者生存 报的什么错??
  • 那颗星_fcaf:大神,我在我的项目中碰见一个bug,就是我点击Link后,地址栏的地址变化,但是页面不跳转,这是为什么呀?
    那颗星_fcaf:@dkvirus 如果想把路由单独写成一个文件怎么写呢,试过都没有成功,必须要写在组件中吗?
    那颗星_fcaf:@dkvirus 我把路由写在父组件中可以,在路由中嵌套写不可以
    dkvirus:dva 有个 api 是注册路由表,作用是当路由变化(浏览器地址栏地址变化)时,会跳转对应页面(src/routes目录下的文件),路由与页面是一一对应的。你的路由变化但没有跳转,请检查下是否路由表配置的有问题。

本文标题:dva 2.0中如何使用代码进行路由跳转

本文链接:https://www.haomeiwen.com/subject/grxlixtx.html