react-router-dom v6应用
作为一名近几年一直在用Vue生态的前端 [ 小程序,UniApp,Sass ]包括一些H5 甚至开发桌端应用也是用的Vue [nwjs打包,Electron插件打包]
对于react基本上每隔一段会看,毕竟是前端中很重要的一个框架,工作中不用可以 但是不能不会 起码到用到的时候能以最快速度适应
一直认为react-router-dom v5 特别麻烦 特别是跟vue-router一对比后 不过两个框架随着升级 写法越来越像了 比如: hook函数 , pinia与mobx , vue-router与react-router-dom v6
V6版本抽离路由表
不好的
// 写法繁杂 不灵活 随着业务增多代码阅读困难
<Routes>
<Route path="/a" element={<A />}>
<Route path="/a/child1" element={<Achild1 />} />
<Route path="/a/child2" element={<Achild2 />} />
</Route>
<Route path="/b" element={<B />} />
<Route path="/c" element={<C />} />
</Routes>
抽离路由表 router/routes.js
/**
* 典型的路由嵌套结构
*
*/
import { Navigate } from 'react-router-dom'
import { lazy } from 'react'
export const routes = [
{
path:'/',
element:()=><Navigate to="/a/achild1" />,
meta:{
name:"A页面",
isLogin:false
}
},
{
path:'/a',
element:lazy(()=>import('./../components/a')),
children:[
{
path:'/a/achild1',
element:lazy(()=>import('./../components/achild/achild1')),
meta:{
name:"A页面",
isLogin:false
}
},
{
path:'/a/achild2',
element:lazy(()=>import('./../components/achild/achild2')),
meta:{
name:"A页面",
isLogin:false
}
},
],
meta:{
name:"A页面",
isLogin:false
}
},
{
path:'/b',
element:lazy(()=>import('./../components/b')),
children:[],
meta:{
name:"B页面",
isLogin:true
}
},
{
path:'/c',
element:lazy(()=>import('./../components/c')),
children:[],
meta:{
name:"C页面",
isLogin:true
}
},
{
path:'/login',
element:lazy(()=>import('./../components/login')),
children:[],
meta:{
name:"登录",
isLogin:false
}
}
]
既然能拿到路由表 无非就是生成 < Routes />嵌套结构 需要的信息 在路由表中都能拿到 不管多少子集路由 一个递归函数即可
<Routes>
<Route path="/a" element={<A />}>
<Route path="/a/child1" element={<Achild1 />} />
<Route path="/a/child2" element={<Achild2 />} />
</Route>
<Route path="/b" element={<B />} />
<Route path="/c" element={<C />} />
</Routes>
router/index.js
import { routes } from "./routes";
import {
Routes,
Route,
useLocation,
useParams,
useSearchParams,
useNavigate,
Navigate,
} from "react-router-dom";
import { Suspense } from "react";
/**
* 处理组件
* @params { Route } props
* 根据不同的业务 处理组件不用的逻辑等
* */
const Element = (props) => {
const {
element: Component,
meta: { name, isLogin },
} = props;
// 将路由信息传递
const navigate = useNavigate();
const location = useLocation();
const params = useParams();
const [usp] = useSearchParams();
// 权限的demo等
// if (name) document.title = name;
// if (isLogin) {
// if (!window.sessionStorage.getItem("login")) {
// return <Navigate to="/login"></Navigate>;
// }
// }
return (
<Component
navigate={navigate}
location={location}
params={params}
usp={usp}
/>
);
};
/**
* 创建 Route
* @params { Array } routes
*
* */
export const createElement = (routes) => {
return (
<>
{routes.map((item) => {
const { path, children } = item;
return (
<Route key={item.path} path={path} element={<Element {...item} />}>
{/* 有子集 , 递归调用 */}
{Array.isArray(children) ? createElement(children) : null}
</Route>
);
})}
</>
);
};
export default function RouterView() {
return (
<Suspense fallback="正在加载中...">
<Routes>{createElement(routes)}</Routes>
</Suspense>
);
}
转载自:https://juejin.cn/post/7281905382484852747