DVA路由配置零踩坑:从零搭到权限守卫全打通
【免费下载链接】dva🌱 React and redux based, lightweight and elm-style framework. (Inspired by elm and choo)项目地址: https://gitcode.com/gh_mirrors/dv/dva
页面一刷新就回到首页,或者两条路由同时把页面渲染出来——路由配置是 DVA 新人翻车最多的地方。下面这套流程,照着敲就能在 DVA 里把导航跑通,不用再去翻官方文档拼凑。
路由到底在干嘛
在单页应用里,路由就是浏览器的地址栏和页面内容之间的调度台(dispatcch)。你输入不同地址,它把对应的组件塞进屏幕,全程不跟服务器要新页面。说白了就是:URL 变了,谁出场、谁退场,路由说了算。
从零搭一条路由
examples/func-test/src/router.js 就是这条路由的完整样子:
import React from 'react'; import { Router, Route } from 'dva/router'; // 路由能力来自 react-router-dom import IndexPage from './routes/IndexPage'; // 首页组件 // 函数形式的 RouterConfig:dva 启动时会把 history 传进来 export default function RouterConfig({ history }) { return ( <Router history={history}> {/* 命中 / 就渲染 IndexPage */} <Route path="/" component={IndexPage} /> </Router> ); }↑ 注册一条/到 IndexPage 的映射,history 由 dva 注入,后面做编程式跳转全靠它。
入口里只要两行把它接上(参考 examples/func-test/src/index.js):
const app = dva(); app.router(require('./router')); // 先注册路由 app.start('#root'); // 再启动,顺序不能反↑ 先注册路由再 start,start 里有硬校验,没注册会直接报错。
让多条路由协作
页面多了以后,三个东西必须登场:exact精确匹配、Switch只渲染第一个命中的、嵌套路由挂子页面。
| 写法 | 行为 | 适合场景 |
|---|---|---|
<Route path="/user" /> | 前缀匹配,/user、/user/1都命中 | 配子路由的父级 |
<Route path="/" exact /> | 只命中/本身 | 首页、独立页 |
<Switch> | 从上往下,只渲染第一个命中的 | 平级路由防冲突 |
import { Router, Route, Switch, Redirect } from 'dva/router'; export default function RouterConfig({ history }) { return ( <Router history={history}> <Switch> <Route path="/" exact component={IndexPage} /> // 只命中 / <Route path="/users" component={UsersPage} /> // /users 及其子路径 <Route path="/user/:id" component={UserDetail} /> <Redirect to="/" /> // 兜底:没命中就回首页 </Switch> </Router> ); }↑ Switch 保证同一时刻只有一个页面出场,Redirect 当 404 兜底。
参数怎么传、跳转怎么做
场景 A:声明式跳转——写个链接就行,适合"点一下去别页":
<Link to="/users">用户列表</Link>
场景 B:编程式跳转——routerRedux.push最常用,它有两个调用位置:
// 位置一:组件里,拿 dispatch 触发 this.props.dispatch(routerRedux.push('/users')); // 位置二:saga 里,请求成功后跳走 yield put(routerRedux.push('/users'));↑ 组件里走 dispatch,saga 里走 put,效果一样,都是改 history。
场景 C:参数怎么取——路径参数写在:id里(match.params.id),查询参数跟在?后面(location.query.name),组件里各取各的。
加个锁:权限守卫
思路很简单:写个高阶组件包住Route,没登录就把Redirect到登录页。
import { Route, Redirect } from 'dva/router'; // 包一层:先验身份,再决定渲染页面还是去登录 function AuthRoute({ component: Component, ...rest }) { return ( <Route {...rest} render={props => isAuthenticated() ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ) } /> ); } // 用法 <AuthRoute path="/dashboard" component={Dashboard} />↑ 守卫逻辑集中在一个地方,以后加角色判断、接口校验都改这一处。
踩过的坑都在这儿
刷新页面直接 404?DVA 默认用 hash history(地址带#),刷新时#后面的部分不会发给服务器,天然免疫。想要干净的地址栏就传createBrowserHistory,但要让服务器把所有路径都回退到 index.html,否则刷新照样 404。
两条路由同时渲染?Route默认前缀匹配,/会命中一切地址,等于全屏套娃。平级路由用Switch包起来,该精确的加exact。
路由根本没生效?九成是app.router()没调用,或者在app.start()之后才注册。路由必须是"函数形式"的组件(接收history返回 JSX),先注册再 start。
下一步学什么
- docs/guide/ —— 官方指南目录,想搞懂 dva 整体概念(model、effect)时来这。
- examples/func-test/ —— 最小可跑示例,本文代码的原型就在这,适合照着逐行敲。
- examples/user-dashboard/ —— 带布局和多页面的完整后台,想加路由前先看它怎么组织 layouts 和 pages。
把上面四段代码敲进你的项目跑起来,你的第一条 DVA 路由就活了 🚀
【免费下载链接】dva🌱 React and redux based, lightweight and elm-style framework. (Inspired by elm and choo)项目地址: https://gitcode.com/gh_mirrors/dv/dva
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考