V6中的路由表及统一管理
一级路由表
const routes = [{
path: '/',
component: () => <Navigate to="/a" />
}, {
path: '/a',
name: 'a',
component: A,
meta: {},
children: aRoutes
}, {
path: '/b',
name: 'b',
component: lazy(() => import('../views/B')),
meta: {}
}, {
path: '/c/:id?/:name?',
name: 'c',
component: lazy(() => import('../views/C')),
meta: {}
}, {
path: '*',
component: () => {
return <Navigate to={{
pathname: '/a',
search: '?from=404'
}} />;
}
}];
二级路由表
const aRoutes = [{
path: '/a',
component: () => <Navigate to="/a/a1" />
}, {
path: '/a/a1',
name: 'a-a1',
component: lazy(() => import(/* webpackChunkName:"AChild" */'../views/a/A1')),
meta: {}
}, {
path: '/a/a2',
name: 'a-a2',
component: lazy(() => import(/* webpackChunkName:"AChild" */'../views/a/A2')),
meta: {}
}, {
path: '/a/a3',
name: 'a-a3',
component: lazy(() => import(/* webpackChunkName:"AChild" */'../views/a/A3')),
meta: {}
}];
递归创建<Route/>
const createRoute = function createRoute(routes) {
return <>
{routes.map((item, index) => {
let { path, children } = item;
// 每一次路由匹配成功,不直接渲染我们设定的组件,而是渲染Element;在Element做一些特殊处理后,再去渲染我们真实要渲染的组件!!
return <Route key={index} path={path} element={<Element {...item} />}>
{/* 基于递归方式,绑定子集路由 */}
{Array.isArray(children) ? createRoute(children) : null}
</Route>;
})}
</>;
};
统一渲染的组件
在这里可以做一些事情「例如:权限/登录态校验,传递路由信息的属性…」
const Element = function Element(props) {
let { component: Component } = props;
// 把路由信息先获取到,最后基于属性传递给组件:只要是基于<Route>匹配渲染的组件,都可以基于属性获取路由信息
const navigate = useNavigate(),
location = useLocation(),
params = useParams(),
[usp] = useSearchParams();
// 最后要把Component进行渲染
return <Component navigate={navigate} location={location} params={params} usp={usp} />;
};
路由容器
export default function RouterView() {
return <Suspense fallback={<>正在处理中...</>}>
<Routes>
{createRoute(routes)}
</Routes>
</Suspense>;
};
创建withRouter
export const withRouter = function withRouter(Component) {
// Component:真实要渲染的组件
return function HOC(props) {
// 提前获取路由信息,作为属性传递给Component
const navigate = useNavigate(),
location = useLocation(),
params = useParams(),
[usp] = useSearchParams();
return <Component {...props} navigate={navigate} location={location} params={params} usp={usp} />;
};
};
V6中自带的解决方案useRoutes
将路由表作为参数,使用element渲染组件,
<Navigate to="/a" />
不能写为()=><Navigate to="/a" />
,且<App/>组件整个需要被HashRouter包裹
const App = function App() {
const element = useRoutes([{
path: '/',
element: <Navigate to="/a" />
}, {
path: '/a',
element: <A />,
children: [{
path: '/a',
element: <Navigate to="/a/a1" />
}, {
path: '/a/a1',
element: <A1 />,
}]
}]);
return <>
<HomeHead />
{element}
</>;
};