封装权限路由组件

202 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

一.思路梳理

  • 定义私有路由组件。在 components 目录中创建 PrivateRoute路由组件:实现路由的登录访问控制逻辑

  • 有token,正常访问

  • 没有token,重定向到登录页面,并传递要访问的路由地址

  • 使用路由组件

  • 将需要权限才能访问的页面,使用私有路由组件

二.token处理

src\utils\storage.ts

// 用来对{token: string, refresh_token: string }做本地持久化

import { Token } from '../types/data'

const TOKEN_KEY = 'geek-app'

// 获取 token
export function getToken (): Token {
  if (localStorage.getItem(TOKEN_KEY)) {
    return JSON.parse(localStorage.getItem(TOKEN_KEY) || '{}')
  } else {
    return {
      token: '',
      refresh_token: ''
    }
  }
}

// 设置 token
export function setToken (data: Token): void {
  localStorage.setItem(TOKEN_KEY, JSON.stringify(data))
}

// 移除 token
export function removeToken (): void {
  localStorage.removeItem(TOKEN_KEY)
}

// 判断是否登录(授权)
export function hasToken (): boolean {
  return !!getToken().token
}

三.代码实现

1.封装组件

src\components\PrivateRoute.tsx

import { hasToken } from '../utils/storage'
import React from 'react'
import { Route, Redirect, RouteProps } from 'react-router-dom'
// children就是要展示的组件
export const PrivateRoute = ({ children, ...rest }: RouteProps) => {
  return (
    <Route
      {...rest}
      render={({ location }) =>
        hasToken()
          ? (children)
          : (
            <Redirect
            to={{
              pathname: '/login',
              state: { from: location }
            }}
          />
            )}
    />
  )
}

注:

  • 若render爆红可能是react-router-dom版本问题,可降版本也可将RouteProps换成any,也可以将render={(props):any

  • location可换成props,state: { from: location }state: { from: location }

  • 使用...rest可以将相应代码规则添加进该路由规则中,如exact

2.使用组件

src\App.tsx

import { PrivateRoute } from './components/PrivateRoute'
function App () {
  return (
  <div className="app">
    <Switch>
     。。。
      <PrivateRoute path="/profile/edit">
      <ProfileEdit />
    </PrivateRoute>
  </div>)
}