1、react-router-config 是一個幫助咱們配置靜態路由的小助手。
其源碼就是一個高階函數 利用一個map函數生成靜態路由vue
import React from "react"; import Switch from "react-router/Switch"; import Route from "react-router/Route"; const renderRoutes = (routes, extraProps = {}, switchProps = {}) => routes ? ( <Switch {...switchProps}> {routes.map((route, i) => ( <Route key={route.key || i} path={route.path} exact={route.exact} strict={route.strict} render={props => ( <route.component {...props} {...extraProps} route={route} /> )} /> ))} </Switch> ) : null; export default renderRoutes;
//router.js 假設這是咱們設置的路由數組(這種寫法和vue很類似是否是?)react
const routes = [ { path: '/', exact: true, component: Home, }, { path: '/login', component: Login, }, { path: '/user', component: User, }, { path: '*', component: NotFound } ]
//app.js 那麼咱們在app.js裏這麼使用就能幫我生成靜態的路由了redux
import { renderRoutes } from 'react-router-config' import routes from './router.js' const App = () => ( <main> <Switch> {renderRoutes(routes)} </Switch> </main> ) export default App
扯了半天,要如何利用這個插件幫咱們路由鑑權呢?
用過vue的小朋友都知道,vue的router.js 裏面添加 meta: { requiresAuth: true }
而後利用導航守衛
數組
router.beforeEach((to, from, next) => { // 在每次路由進入以前判斷requiresAuth的值,若是是true的話呢就先判斷是否已登錄 })
2、基於相似vue的路由鑑權想法,咱們稍稍改造一下react-router-config
// utils/renderRoutes.jsreact-router
import React from 'react' import { Route, Redirect, Switch } from 'react-router-dom' const renderRoutes = (routes, authed, authPath = '/login', extraProps = {}, switchProps = {}) => routes ? ( <Switch {...switchProps}> {routes.map((route, i) => ( <Route key={route.key || i} path={route.path} exact={route.exact} strict={route.strict} render={(props) => { if (!route.requiresAuth || authed || route.path === authPath) { return <route.component {...props} {...extraProps} route={route} /> } return <Redirect to={{ pathname: authPath, state: { from: props.location } }} /> }} /> ))} </Switch> ) : null export default renderRoutes
修改後的源碼增長了兩個參數 authed 、 authPath 和一個屬性 route.requiresAuth
而後再來看一下最關鍵的一段代碼app
if (!route.requiresAuth || authed || route.path === authPath) { return <route.component {...props} {...extraProps} route={route} /> } return <Redirect to={{ pathname: authPath, state: { from: props.location } }} />
很簡單 若是 route.requiresAuth = false 或者 authed = true 或者 route.path === authPath(參數默認值'/login')則渲染咱們頁面,不然就渲染咱們設置的authPath頁面,並記錄從哪一個頁面跳轉。dom
相應的router.js也要稍微修改一下函數
const routes = [ { path: '/', exact: true, component: Home, requiresAuth: false, }, { path: '/login', component: Login, requiresAuth: false, }, { path: '/user', component: User, requiresAuth: true, //須要登錄後才能跳轉的頁面 }, { path: '*', component: NotFound, requiresAuth: false, } ]
//app.jsui
import React from 'react' import { Switch } from 'react-router-dom' //import { renderRoutes } from 'react-router-config' import renderRoutes from './utils/renderRoutes' import routes from './router.js' const authed = false // 若是登錄以後能夠利用redux修改該值(關於redux不在咱們這篇文章的討論範圍以內) const authPath = '/login' // 默認未登陸的時候返回的頁面,能夠自行設置 const App = () => ( <main> <Switch> {renderRoutes(routes, authed, authPath)} </Switch> </main> ) export default App
//登錄以後返回原先要去的頁面login函數 login(){ const { from } = this.props.location.state || { from: { pathname: '/' } } // authed = true // 這部分邏輯本身寫吧。。。 this.props.history.push(from.pathname) }
以上~修改了部分源碼並完成了咱們想要的效果。this