React 配置路由并添加权鉴

React 项目使用 TypeScriptHooks API,本文介绍路由的基本配置和权鉴配置。

建立 ./src/router/index.ts 文件,配置路由路径与对应页面组件。

import { RouteConfig } from 'react-router-config';

import Login from 'src/views/Login/login';
import Home from 'src/views/Home/home';
import Welcome from 'src/views/Home/Welcome';

const routes: RouteConfig = [
  {
    path: '/login',
    component: Login,
    meta:{ 
      name: 'login', 
      title: '登录' 
    }
  },
  {
    path: '/home',
    component: Home,
    meta:{ 
      name: 'home', 
      title: '主页' 
    }
    routes: [
      {
        path: '/home/welcome',
        component: Welcome,
        meta:{
          name: 'welcome', 
          active: 'welcome',
          title: '欢迎页面' 
        }
      },
    ]
  }
]
export default routes;

./src/model/route.ts 这里集中定义了路由组件的接口类型

import { FC } from 'react';

interface IMeta {
  name: string;
  active?: string;
  title?: string;
}

interface routeInterface {
  path: string;
  component: FC;
  meta?: IMeta;
  redirect?: string;
  auth?: boolean;
  routes?: Array<any>;
}

export type RouteInterface = routeInterface

./src/app.tsx 修改路由相关

import { FC, useReducer } from 'react';
import { BrowserRouter as Router, Redirect, Switch } from 'react-router-dom';
import routes from 'src/router';
import RouteWithSubRoutes from 'src/components/route';
import { RouteInterface } from 'src/model/route';

const App: FC = () => {
  return (
	...
	  <Router>
        <Switch>
          <Redirect exact from="/" to="/login" />
          {routes.map((route: RouteInterface, i: number) => {
            return RouteWithSubRoutes(route, i)
          })}
        </Switch>
      </Router>
    ...
  )
}
export default App;
  • ./src/app.tsx 只列出与路由相关代码,
  • <Switch> 中先定义 <Redirect> 重定向默认跳转到登录页。
  • 这里定义了一个路由组件 RouteWithSubRoutes 重定向之后,遍历之前定义的 ./src/router/index.ts 路由配置文件,并输出这个路由组件返回的内容。

./src/components/route.tsx 即刚定义的 RouteWithSubRoutes 组件。

import { Route, Redirect } from 'react-router-dom';
import { RouteInterface } from 'src/model/route';

const RouteWithSubRoutes = (route: RouteInterface, index: number ) => {
  return (
    <Route
      key={index}
      path={route.path}
      render={props => 
        <route.component {...props} routes={route.routes} />
      }
    />
  );
}

export default RouteWithSubRoutes

如此,简单的路由配置好了,启动项目默认跳转到登录页 /login,如果访问 /home/welcome 就直接跳转到登录之后的欢迎页。

现在要给路由加权鉴,简单点的需求是让登录页不设权鉴,而让登录后 /home 相关的所有子路由都加上权鉴,并根据登录状态判断能否访问。

修改一下 ./src/router/index.ts 文件

...
const routes: RouteConfig = [
  {
    path: '/login',
    component: Login,
    meta:{ 
      name: 'login', 
      title: '登录' 
    },
    auth: false
  },
  {
    path: '/home',
    component: Home,
    meta:{ 
      name: 'home', 
      title: '主页' 
    },
    auth: true,
    routes: [
      {
        path: '/home/welcome',
        component: Welcome,
        meta:{
          name: 'welcome', 
          active: 'welcome',
          title: '欢迎页面' 
        },
        auth: true
      },
    ]
  }
]
export default routes;
  • 给每个路由和子路由加上 authtrue 代表有权鉴,false 代表没有。

修改 ./src/components/route.tsx

import { Route, Redirect } from 'react-router-dom';
import { RouteInterface } from 'src/model/route';
import { renderRoutes  } from 'react-router-config';
import store from 'src/store';

// 渲染结果
const myRender = ( route:RouteInterface, index:number, props:any ) => {

  let token = store.getState().user || null;
  
  // 登录状态
  if( token ){
    // 已登录状态跳转到登录页
    if ( route.auth ) {
      console.log('已登录,有权鉴');
      return <route.component items={route} {...props} routes={route.routes} />
    } else {
      console.log('已登录,没有权鉴');
      return <Redirect to={{ pathname:'/home' }} />
    }
  } else {
    // 非登录状态下,通过权鉴时
    if ( route.auth ) {
      console.log('非登录状态下,通过权鉴时');
      return (
        <Redirect exact to={{ pathname: '/login' }} />
      );
    } else {
      console.log('非登录状态下,没通过权鉴时');
      return <route.component {...props} routes={renderRoutes(route.routes)} />
    }
  }

}

const RouteWithSubRoutes = (route: RouteInterface, index: number ) => {
  return (
    <Route
      key={index}
      path={route.path}
      render={props => 
        myRender(route,index,props)
      }
    />
  );
}

export RouteWithSubRoutes
  • 把渲染部分独立成 myRender 方法
  • 首先通过 token 判断登录状态,分别在登录和没登录两个逻辑中再次通过 auth 判断有无权鉴。
    1. 在非登录状态访问有权鉴的页面会跳到登录页。
    2. 在非登录状态访问没权鉴的页面,好像只有登录页符合这样的条件。
    3. 登录状态访问有权鉴的页面正常返回子路由组件。
    4. 登录状态访问没权鉴的页面,可以定义个 404 页面并返回,我这里只重定向到 ./home 路由。

至此,权鉴添加完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值