react 封装路由

106 阅读2分钟

1. 项目结构

1689691319419.jpg

main.js代码内容如下

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
//import Baseroute from "./router/index2"
import {BrowserRouter} from "react-router-dom"

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
   
    {/* <Baseroute></Baseroute> */}
  </React.StrictMode>,

App.js代码内容如下

import { Outlet,Link,useRoutes} from 'react-router-dom'
import './App.css'
import routes from './router/index'
function App() {
  const routeview=useRoutes(routes)
  return (
    <div className="appname">
     {/* <Link to="/home">首页</Link>
     <Link to="/about">关于页</Link>
     <Link to="/view">视图页</Link> */}
     {/* <Outlet></Outlet> */}
      {routeview}
    </div>
  )
}

export default App

亦或者对app.js进行进一步封装,实现路由守卫等功能

import { useEffect } from 'react'
import { useRoutes, useLocation,useNavigate } from "react-router-dom"
import router from "./router"
import { message } from "antd"

// 去往登录页的组件
function ToLogin(){
  const navigateTo = useNavigate()
  // 加载完这个组件之后实现跳转
  useEffect(()=>{
    // 加载完组件之后执行这里的代码
    navigateTo("/login");
    message.warning("您还没有登录,请登录后再访问!");
    console.log('您还没有登录,请登录后再访问!')
  },[])
  return <div></div>
}
// 去往首页的组件
function ToPage1(){
  const navigateTo = useNavigate()
  // 加载完这个组件之后实现跳转
  useEffect(()=>{
    // 加载完组件之后执行这里的代码
    navigateTo("/home");
    message.warning("您已经登录过了!");
  },[])
  return <div></div>
}
// 手写封装路由守卫
function BeforeRouterEnter(){
  const outlet = useRoutes(router);

  /*
    后台管理系统两种经典的跳转情况:
    1、如果访问的是登录页面, 并且有token, 跳转到首页
    2、如果访问的不是登录页面,并且没有token, 跳转到登录页
    3、其余的都可以正常放行
  */
    const location = useLocation()
    let token = localStorage.getItem("lege-react-management-token");
    //1、如果访问的是登录页面, 并且有token, 跳转到首页
    if(location.pathname==="/login" && token){
      // 这里不能直接用 useNavigate 来实现跳转 ,因为需要BeforeRouterEnter是一个正常的JSX组件
      return <ToPage1 />
    }
    //2、如果访问的不是登录页面,并且没有token, 跳转到登录页
    if(location.pathname!=="/login" && !token){
      return <ToLogin />
    }

    return outlet
}


function App() {  
  return (
    <div className="App">

      {/* <Link to="/home">Home</Link> |
      <Link to="/about">About</Link> |
      <Link to="/user">User</Link> */}

      {/* 占位符组件,类似于窗口,用来展示组件的,有点像vue中的router-view */}
      {/* <Outlet></Outlet> */}
      {/* {outlet} */}
      <BeforeRouterEnter />
    </div>
  )
}

export default App

router下index.js代码内容如下

import {Routes,Route,BrowserRouter,Navigate} from "react-router-dom"
import React,{lazy,Suspense} from "react"
import Home from "../views/home"
// import About from "../views/about"
// import View from "../views/view"
const About=lazy(()=>import ("../views/about"));
const View=lazy(()=>import ("../views/view"));
const withLoadingComponent=(comp:JSX.Element)=>{
 return (<Suspense fallback={<div>loading</div>}>
      {comp}
   </Suspense>)
}
const routes=[
{
 path:'/',
 element: <Navigate to="/home"></Navigate> //重定向首页
},
{
    path:'/home',
    element: <Home></Home>
 },
 {
    path:'/about',
    element:withLoadingComponent(<About></About>)
 },
 {
    path:'/View',
    element:withLoadingComponent(<View></View>) 
 }
]
export default routes

views下视图代码如下

home视图

const View= () => {
 return (<div>我是首页</div>)

};

export default View

view视图

const View=()=>{
    return (<div>我是视图页</div>)
}
export default View

about视图

 const View=()=>{
     return (<div>我是关于页</div>)
 }
 export default View