# React 管理系统 **Repository Path**: hepingkang/react-management-system ## Basic Information - **Project Name**: React 管理系统 - **Description**: 基于 react 18 、ts、react-router-dom 6、 ant-design、vite 开发的通用模板 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 2 - **Created**: 2022-11-18 - **Last Updated**: 2023-07-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: React, TypeScript, Redux, Ant-Design ## README ## 一、配置项目路径别名 #### 1. 路径别名 1. 需要手动配置 @ 符号的指向 2. 在 vite.config.ts 中添加配置 ```js import path from 'path'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], resolve: { alias: { // dirname 目录名 '@': path.resolve(__dirname, './src') } } }) ``` ## 二、路由配置(组件写法) #### 1. 展示 ```js // router 文件夹下的 index import App from '../App' import Home from '../views/Home' import About from '../views/About' // BrowserRouter history 模式 (/home) // HashRouter hash 模式 (#home) import { BrowserRouter, Routes, Route } from 'react-router-dom' const baserRouter = () => ( // 一个 route 就是一个路由 // path 路由路径 // element 路由路径对应的组件 }> // 子组件,所有组件都渲染在 app 组件中 } /> } /> ) // 导出配置好的路由组件 export default baserRouter // main // 导入路由组件 import BaserRouter from './router' ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( // 渲染 , ) // app import { Outlet } from 'react-router-dom' function App() { const [count, setCount] = useState(0) return (
{/* 路由占位符,用于展示路由组件,和 vue 中 router-view 差不多 */}
) } export default App ``` #### 2. Navigate(重定向) ```js // Navigate 重定向组件 import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' }> // 匹配到 / 路由的时候,重定向到 home 路由 } /> } /> } /> ``` ## 三、路由配置(对象写法) #### 1. 展示 ```js // index import { Navigate } from 'react-router-dom' const routes = [ { path: '/', element: , }, { path: '/home', element: , }, { path: '/about', element: , }, ] export default routes // main import { BrowserRouter } from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( // 使用 history 模式 , ) // app // 导入路由表 import routes from './router' import { useRoutes } from 'react-router-dom' function App() { // useRoutes 接收路由表,返回当前匹配的路由元素展示对应的组件 const oulet = useRoutes(routes) return
{oulet}
} export default App ``` #### 2. 懒加载 ```js // 引入 react 中 lazy(懒加载)函数 import React, { lazy } from 'react' import { Navigate } from 'react-router-dom' // 通过 lazy 方法按需导入组件 // 懒加载模式,外层需要套一层 loading 的提示加载组件 const Home = lazy(() => import('../views/Home')) const About = lazy(() => import('../views/About')) // 高阶组件 const withLoadingComp = (comp: JSX.Element) => ( // 只要是 lazy 懒加载模式,就必须加上 React.Suspense 组件 // fallback 组件加载前展示的内容 加载中....}>{comp} ) const routes = [ { path: '/', element: , }, { path: '/home', element: withLoadingComp(), }, { path: '/about', element: withLoadingComp(), }, ] ``` ## 四、编程式导航 #### 1. 跳转到对应页面 ```js // 1. 导入 useNavigate 方法 import { useNavigate } from 'react-router-dom' // 2. 接收返回的跳转方法 const navigateTo = useNavigate() // 3. 跳转到对应页面 navigateTo('/home') ``` ## 五、嵌套路由 ```js // 写法1 const routes = [ { path: '/', // 重定向 element: , }, { path: '/', element: , // 子路由,下面路由都将渲染到 home 页面上 children: [ { path: '/about', element: withLoadingComp(), }, { path: '/page', element: withLoadingComp(), }, ], }, ] // ts 函数写法 const getRoutes = ( path: React.Key, element: React.ReactNode, children?: object[], ): object => ({ path, element, children }) const routes = [ getRoutes('/', ), getRoutes('/', , [ getRoutes('about', withLoadingComp()), getRoutes('page', withLoadingComp()), ]), ] ``` ## 六、封装路由前置守卫 ```js // permission import { useLocation, useNavigate, useRoutes } from 'react-router-dom' import routes from '@/router' import { useEffect } from 'react' import { message } from 'antd' /* 后台管理系统两种经典的跳转情况: 1、如果访问的是登录页面, 并且有token, 跳转到首页 2、如果访问的不是登录页面,并且没有token, 跳转到登录页 3、其余的都可以正常放行 */ // 路由守卫 const BeforeRouterEnter = () => { const oulet = useRoutes(routes) const navgateTO = useNavigate() // 1. 拿到访问地址和 token const location = useLocation() let token = localStorage.getItem('token') // 2. 组件加载完毕进行判断 useEffect(() => { // 3. 如果访问的是登录页面, 并且有token, 跳转到首页 if (location.pathname === '/login' && token) { message.success('您已经登录!') // 进行跳转 return navgateTO('/page') } // 4. 如果访问的不是登录页面,并且没有token, 跳转到登录页 if (location.pathname !== '/login' && !token) { message.error('您还未登录!') // 进行跳转 return navgateTO('/login') } }) // 5. 其余正常放行 return oulet } export default BeforeRouterEnter // app import Oulet from './permission' function App() { return (
{/* 占位符组件,类似于窗口,用来展示组件的,有点像vue中的router-view */}
) } export default App ```