动态路由
第一想法是用lazy(() => import('./pages/page1/index.tsx'))
但是import参数不支持变量,只能是写死的路径。
import()的路径必须是静态字符串,因为构建工具需要在构建阶段解析模块路径
vite的import.meta.glob方法动态导入组件
const modules = import.meta.glob("./pages/*.jsx");
console.log(modules);
动态拼接route
接口获取权限
export const getAdminMenus = () => {
return new Promise((resolve) => {
window.setTimeout(() => {
resolve([
{
name: 'page1',
route: '/page1',
filePath: '/page1/index.tsx',
},
]);
}, 1000);
});
};
整理
import.meta.glob
const components = Object.keys(modules).reduce((prev, cur) => {
prev[cur.replace('./pages', '')] = modules[cur];
return prev;
}, {}) ;
//components:{/page1/index.tsx : import("/src/pages/page1/index.tsx")}
useEffect处理用户权限
useEffect(() => {
getAdminMenus().then((adminMenus: any) => {
setMenus(adminMenus);
setLoading(false);
// 获取菜单后动态添加路由
router.routes[0].children = adminMenus.map((menu: any) => ({
path: menu.route,
Component: lazy(components[menu.filePath])
}));
})
}, []);
route简单使用
初始化
npm create vite
pnpm i react-router-dom
使用
createBrowserRouter传入数组对象组件
RouterProvider组件传入数组
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import Page1 from './pages/page1'
const router = createBrowserRouter([{
path: '/page1',
Component: Page1,
}])
function App() {
return (
<RouterProvider router={router} />
)
}
export default App
重定向
const router = createBrowserRouter([{
path: '/page1',
Component: Page1,
},{
path: '/',
element: <Navigate to="/page1" />,
}])
自定义404页面
const router = createBrowserRouter([{
path: '/page1',
Component: Page1,
},{
path: *,
Component: NotFound,
}])
Link与Outlet
Outlet是一个占位符组件,用于渲染当前路由的子路由组件。
const router = createBrowserRouter([{
path: '/',
Component: Layout,
children: [{
path: '/page1',
Component: Page1,
}],
}, {
path: '*',
Component: NotFound,
}])
------分割线-----
function Layout() {
return (
<div>
<ul>
<li>
<Link to="/page1">page1</Link>
</li>
</ul>
<Outlet />
</div>
);
}
路由按需加载
借助react的lazy和Suspense可以轻松的实现按需加载。
const router = createBrowserRouter([
{
path: '/',
Component: Layout,
children: [
{
path: '/page1',
Component: lazy(() => import('./pages/page1/index.tsx')),
}
],
},
{
path: '*',
Component: NotFound,
}
])
Outlet组件需要用Suspense包起来,再加上一个loading。
<Suspense fallback={<div>Loading ...</div>}>
<Outlet />
</Suspense>