title: React自定义路由以及路由守卫
date: 2022-10-08 21:39:17
tags:
react路由v6版本提供了和Vue相像的路由表,但是相比Vue还是少了一点东西。官方所谓的“提供更多自由度”好是好。但我觉得太高的自由度对于开发来说效率上会大大折扣。重复性的造轮子倒不如使用提供的。。。
Vue提供的现成的路由Api方便了对路由的监听,在这两个钩子中可以对路由进行常用的 鉴权 等操作…
特别方便
// ...路由表
const routes = [
// ...
{
path: '*',
component: () => import('@/components/common/404/Error.vue'),
meta: {
title: '404-s.kr'
},
},
// ...
]
// 生成路由对象
const router = new VueRouter({
mode: 'history',
routes,
scrollBehavior(to, from, savedPosition) { // 解决vue页面跳转只有页面不是在顶部的问题
// savedPosition 会在你使用浏览器前进或后退按钮时候生效
if (savedPosition) {
return {
selector: savedPosition
}
} else {
return { x: 0, y: 0 }
}
}
})
//挂载路由导航守卫
router.beforeEach((to, from, next) => {
// 路由跳转开始
})
router.afterEach((to, from) => {
// 路由跳转完毕
})
在React中,Router v5版本没有路由表这种东西,需要自己写
等…
但在v6版本中可以配置路由表,通过useRoutes(routes)
可以生成v5当中的路由配置
V6版本当中要自己封装一套类
useRoutes(routes)
生成路由配置
路由的配置要根据情况!直接上代码:
// React 组件懒加载
// 封装快速导入工具函数
const lazyLoad = (moduleName: string) => {
NProgress.start() // 显示进度条
const Module = lazy(() => import(`pages/${moduleName}`));
return <Module></Module>;
};
// 路由鉴权组件
// 高阶组件--将传入的路由组件进行鉴权判定
const Appraisal = ({ children }: any) => {
if (!getCookie("userinfo")) {
// 判断本地 是否 存有 Cookie
// 如果没有 就 重定向到登陆页面
message.warning('请先登录~');
return <Navigate to="/login" replace />;
} else {
return children
}
};
interface Router {
path: string, // 路由路径
children?: Array<Router>, // 子路由
element: any, // 路由页面
auth?: boolean // 需要路由鉴权
}
const routes: Array<Router> = [
// ...
// 主页
{
path: '/home',
element: <Home></Home>,
},
// 搜索
{
path: '/search',
element: lazyLoad('Search'),
children: [
{
path: 'product/:name',
element: lazyLoad('Product')
},
{
path: 'activity',
element: lazyLoad('Activity')
},
{
path: 'show',
element: lazyLoad('Show')
},
{
path: '/search',
element: <Navigate to="/search/product"></Navigate>
}
]
},
// 底部路由跳转
{
path: '/about', // 关于我们
element: lazyLoad('About')
},
// ...
];
// 通过 MyRouter 函数动态生成路由配置
// 这种 路由生成仅限两层路由
const MyRouter = () => {
return (
<Suspense fallback={<Loading />}>
<Routes>
{
routes.map((item, index) => {
// 判断是否需要鉴权
if (item.auth) {
return <Route key={index} path={item.path} element={<Appraisal>{item.element}</Appraisal>}></Route>
}
// 判断是否有子路由
return (item.children ?
<Route key={index} path={item.path} element={item.element}>
{
item.children.map((e, i) =>
<Route key={i} path={e.path} element={e.element} />
)
}
</Route> :
<Route key={index} path={item.path} element={item.element}></Route>
)
})
}
</Routes>
</Suspense>
)
}
export default MyRouter;
有些情况下,我们所展示的页面有些是需要公共底部导航的,但是有些页面是不需要的。我就需要根据实际情况配置路由;(此配置没有路由守卫)
import { lazy,Suspense } from 'react'
import App from 'App'
import {
BrowserRouter,
Routes,Route,
Navigate
} from "react-router-dom";
interface routeType{
path?:string
element?:React.ReactNode
children?:Array<routeType>
}
// 定义数组每一项的接口
interface IRoute {
path:string;
component:React.FC;
children?:Array<IRoute>
}
const router_arr:IRoute[] = [
{
path:"/",
component:App,
children:[
{path:"/home",component:lazy(()=>import("pages/Home"))},
{path:"/sort",component:lazy(()=>import("pages/Sort"))},
{path:"/shopcar",component:lazy(()=>import("pages/ShopCar"))},
{path:"/usercenter",component:lazy(()=>import("pages/UserCenter"))},
{path:"/",component:lazy(()=>import("pages/Home"))},
]
},
{
path:"/login",
component:lazy(()=>import("pages/Login"))
},
{
path:"/search",
component:lazy(()=>import("pages/Search"))
},
{
path:"/register",
component:lazy(()=>import("pages/Register"))
},
{
path:"*",
component:lazy(()=>import("pages/404"))
}
]
const MyRouter = ()=>(
<BrowserRouter>
<Suspense fallback={<h1></h1>}>
<Routes>{
router_arr.map((item,index)=>{
if (item.path==='*') {
return <Route key={index} path={item.path} element={<item.component/>}></Route>
}
return (item.children ?
<Route key={index} path={item.path} element={<item.component/>}>
{
item.children.map((e,i)=>{
if (e.path === '/') {
return <Route key={i} path={e.path} element={<Navigate to="/home"/>}/>
}
return <Route key={i} path={e.path} element={<e.component/>}/>
})
}
</Route>:
<Route key={index} path={item.path} element={<item.component/>}></Route>
)})
}</Routes>
</Suspense>
</BrowserRouter>
)
export default MyRouter
这种配置下的路由,就需要将
配置到入口函数:
这种路由配置,可解决部分页面需要底部导航,而有些页面却不需要。就比如说登录页,注册页等等。。
import MyRouter from 'router/router';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<MyRouter />
);
而App组件中就需要这样写:
...
function App() {
return (
<>
<Outlet/>
<FooterLink/>
</>
);
}
...