0%

React自定义路由以及路由守卫

React自定义路由以及路由守卫

react路由v6版本提供了和Vue相像的路由表,但是相比Vue还是少了一点东西。官方所谓的“提供更多自由度”好是好。但我觉得太高的自由度对于开发来说效率上会大大折扣。重复性的造轮子倒不如使用提供的。。。🤔

Vue中的路由

Vue提供的现成的路由Api方便了对路由的监听,在这两个钩子中可以对路由进行常用的 鉴权 等操作…

特别方便😍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// ...路由表
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路由

在React中,Router v5版本没有路由表这种东西,需要自己写<Route></Route>等…

但在v6版本中可以配置路由表,通过useRoutes(routes)可以生成v5当中的路由配置

V6版本当中要自己封装一套类useRoutes(routes)生成路由配置

路由的配置要根据情况!直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// 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;

情况二

有些情况下,我们所展示的页面有些是需要公共底部导航的,但是有些页面是不需要的。我就需要根据实际情况配置路由;(此配置没有路由守卫)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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

这种配置下的路由,就需要将<MyRouter/>配置到入口函数:

这种路由配置,可解决部分页面需要底部导航,而有些页面却不需要。就比如说登录页,注册页等等。。

1
2
3
4
5
6
7
8
9
import MyRouter from 'router/router';

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);

root.render(
<MyRouter />
);

而App组件中就需要这样写:

1
2
3
4
5
6
7
8
9
10
11
12
...

function App() {
return (
<>
<Outlet/>
<FooterLink/>
</>
);
}

...