网站项目运营方案,网站作业,如何查询百度收录,wordpress 简洁模板动态路由
路由分成两部分#xff1a; 静态路由#xff0c;固定的部分#xff0c;如主页、404、login 这几个页面 动态路由#xff0c;变化的部分#xff0c;经常是主页内的嵌套路由#xff0c;比如 Student、Teacher 这些
动态路由应该是根据用户登录后#xff0c;根…动态路由
路由分成两部分 静态路由固定的部分如主页、404、login 这几个页面 动态路由变化的部分经常是主页内的嵌套路由比如 Student、Teacher 这些
动态路由应该是根据用户登录后根据角色的不同从后端服务获取因为这些数据是变化的所以用 mobx 来管理
在src\store\路径下新建RoutesStore.tsx
import axios from axios;
import {LoginReq,LoginResp,Menu,MenuAndRoute,Route,
} from ../model/Student;
import R from ../model/R;
import { makeAutoObservable, runInAction } from mobx;
import { Link, Navigate, RouteObject } from react-router-dom;
import { load } from ../router/MyRouter;
import A8Main from ../pages/A8Main;
import A8NotFound from ../pages/A8NotFound;
import { ItemType } from antd/es/menu/hooks/useItems;
import Icon from ./Icon;
//其中 convertMenu 为核心方法负责将服务器返回的 Menu 转换成 antd Menu 组件需要的 Menu
function convertMenu(m: Menu): ItemType {const Label m.routePath ? Link to{m.routePath}{m.label}/Link : m.label;return {key: m.key,label: Label,icon: Icon name{m.icon}/Icon,children: m.children m.children.map(convertMenu),};
}
class RoutesStore {dynamicRoutes: Route[] [];dynamicMenus: Menu[] [];token: string ;message: string ;state: string pending;async login(loginReq: LoginReq) {this.state pending;const resp1 await axios.postRLoginResp(http://localhost:8080/api/loginJwt,loginReq);if (resp1.data.code 999) {const resp2 await axios.getRMenuAndRoute(http://localhost:8080/api/menu/${loginReq.username});runInAction(() {this.dynamicRoutes resp2.data.data.routeList;localStorage.setItem(dynamicRoutes,JSON.stringify(this.dynamicRoutes));this.dynamicMenus resp2.data.data.menuTree;localStorage.setItem(dynamicMenus, JSON.stringify(this.dynamicMenus));this.token resp1.data.data.token;localStorage.setItem(token, this.token);this.state success;});} else {runInAction(() {this.state error;this.message resp1.data.message || 未知错误;});}}/* async fetch(username: string) {const resp await axios.getRMenuAndRoute(http://localhost:8080/api/menu/${username});runInAction(() {this.dynamicRoutes resp.data.data.routeList;//当在浏览器地址栏重新输入路径的时候会重新向7070服务器发送一个请求导致RoutesStore.tsx重新执行//导致路由对象重新被创建那么登录之后获得的动态路由数据就会丢失所以为了防止这种情况把登录后获得的//路由数据存入到localStorage中localStorage.setItem(dynamicRoutes, JSON.stringify(this.dynamicRoutes));this.dynamicMenus resp.data.data.menuTree;localStorage.setItem(dynamicMenus, JSON.stringify(this.dynamicMenus));});} */get routes() {const staticRoutes: RouteObject[] [{path: /login,element: load(A8Login),},{path: /,element: A8Main/A8Main,children: [],},{path: /404,element: A8NotFound/A8NotFound,},// 使用这个路径上面的路径匹配不到时显示notFound页面但是路径还是输入的路径不变{ path: /*, element: A8NotFound/A8NotFound },// 使用这种路径写法的时候上面的路径匹配不到时页面是重定向到notFound,路径会跳转到404{path: /*,element: Navigate to{/404}/Navigate,},];staticRoutes[1].children this.dynamicRoutes.map((r) {return { path: r.path, element: load(r.element) };});return staticRoutes;}get menus() {return this.dynamicMenus.map(convertMenu);}get username() {if (this.token.length 0) {return ;}
//token 的前两部分都可以解码出来其中 [1] 就是 token 的内容部分const json atob(this.token.split(.)[1]);//parse方法把字符串还原成对象return JSON.parse(json).sub;}constructor() {makeAutoObservable(this);//页面刷新会重新调用构造器这个时候从localStorage中获取存储的路由数据const routesJson localStorage.getItem(dynamicRoutes);this.dynamicRoutes routesJson ? JSON.parse(routesJson) : [];const menusJson localStorage.getItem(dynamicMenus);this.dynamicMenus menusJson ? JSON.parse(menusJson) : [];}reset() {localStorage.removeItem(dynamicRoutes);this.dynamicRoutes [];localStorage.removeItem(dynamicMenus);this.dynamicMenus [];localStorage.removeItem(token);this.token ;this.state pending;}
}
export default new RoutesStore();其中用 localStorage 进行了数据的持久化避免刷新后丢失数据 跳转若发生错误可能是因为组件懒加载引起的需要用 Suspense 解决 root.render(ConfigProvider locale{zhCN}BrowserRouterSuspense fallback{h3加载中.../h3}MyRouter/MyRouter/Suspense/BrowserRouter/ConfigProvider
)