番禺人才网入库考试夫唯老师seo
2026/1/2 11:04:14 网站建设 项目流程
番禺人才网入库考试,夫唯老师seo,电子商务网站建设与管理的实践报告,软文推广是什么意思?#上一篇文章讲述了三级路由缓存的一个ParentView这个方案#xff0c;它是可以实现三级路由缓存的问题#xff0c;但是经过测试反馈#xff0c;发现有一个严重的bug#xff0c;就是打开的三级路由页面有几个#xff0c;新打开的三级路由页面的onMounted或者onBeforeMount 就…#上一篇文章讲述了三级路由缓存的一个ParentView这个方案它是可以实现三级路由缓存的问题但是经过测试反馈发现有一个严重的bug就是打开的三级路由页面有几个新打开的三级路由页面的onMounted或者onBeforeMount 就会触发n1次 导致接口重复被调用#这就使我不得不再次研究如何更优雅且没有bug的来实现Vue三级及以上路由无法缓存的问题重新思考既然二级路由可以实现缓存那么可不可以把三级以及三级以上路由转化为二级路由呢有的同学说路由本来就是三级的转为二级菜单那里就不可以使用了那么有没有一个方法既不影响页面菜单那里的UI展示效果又能把三级路由转为二级路由呢代码实现这里需要注意路由配置还是保持多级嵌套的形式而这个配置并非最终注册使用的路由仅仅是提供侧边栏导航菜单使用同时再生成一份用于动态注册路由的数据图例如果没看明白的话可以看下面两组数据。一、处理后端返回的菜单数据(原始数据还是原始数据的处理方式)import { RouteRecordRaw } from vue-router; import { defineStore } from pinia; import { constantRoutes } from /router; import { store } from /store; const modules import.meta.glob(../../views/**/**.vue); const Layout () import(/layout/index.vue); const Other () import(/layout/other.vue); const filterAsyncRoutes (routes: [],basepath:string) { const asyncRoutes: RouteRecordRaw[] []; routes.sort((item1, item2) { return item1.sort - item2.sort }).forEach((route) { const tmpRoute { // path: basepath/route.menuUrl, // component: basepath / route.menuUrl, // name: route.menuName, // meta: { title: route.menuName, icon: route.icon, show: false, keepAlive: true }, path: basepath / route.resourceUrl, component: basepath / route.resourceUrl, name: route.resourceName, meta: { title: route.resourceName, type: route.resourceType, icon: route.icon, show: route.isShow, keepAlive: true, sort: route.sort }, children: route.childrenList.length 0 ? route.childrenList : [] }; // ES6扩展运算符复制新对象 //解析路径(旧的逻辑) if (tmpRoute.component?.toString() Layout) { tmpRoute.component Layout; } else { const component modules[../../views${tmpRoute.component}.vue]; if (component) { tmpRoute.component component; } else { if(tmpRoute.children.length 0){ tmpRoute.component Other }else { tmpRoute.component modules[../../views/error-page/404.vue]; } } } if (tmpRoute.children tmpRoute.children.length 0) { tmpRoute.children filterAsyncRoutes(tmpRoute.children.sort((item1, item2) { return item1.sort - item2.sort // if (item1.sort item2.sort) { // return 1; // } else { // return -1; // } }), basepath / route.resourceUrl); // basepath / route.menuUrl } asyncRoutes.push(tmpRoute); }); return asyncRoutes; }; // setup export const usePermissionStore defineStore(permission, () { //当前模块的id const menuid refstring() //当前路径 const currpath refstring() // state const routes refRouteRecordRaw[]([]); // actions function setRoutes(newRoutes: RouteRecordRaw[]) { routes.value constantRoutes.concat(newRoutes); } function setMenuid(id: string) { menuid.value id } function setCurrPath(path: string) { currpath.value path; } /** * 生成动态路由 * * param childrenList 用户的菜单集合 * returns */ function generateRoutes(childrenList: []) { //构成菜单树形结构 //1.第一级 默认为 头部 //2.第二级 为功能菜单 //拼转成前端数据 const asyncRoutes: RouteRecordRaw[] []; childrenList.sort((item1, item2) { // if (item1.sort item2.sort) { // return 1; // } else { // return -1; // } return item1.sort - item2.sort }).map((model) { //模块 const tmp { path: model.url, component: Layout, redirect: model.url, name: model.moduleName, meta: { title: model.moduleName, id: model.id, icon: model.icon, show: true, keepAlive: true }, // children: model.accessibleMenuList.length 0 ? model.accessibleMenuList : [] children: model.childrenList.length 0 ? model.childrenList : [] } if (tmp.children tmp.children.length 0) { tmp.children filterAsyncRoutes(tmp.children, model.url); } asyncRoutes.push(tmp); }); //设置当前模块 // console.log(当前路径的数据, asyncRoutes) return new PromiseRouteRecordRaw[]((resolve, reject) { setRoutes(asyncRoutes); resolve(asyncRoutes); }); } return { routes, menuid, currpath, setRoutes, generateRoutes, setMenuid, setCurrPath }; }); // 非setup export function usePermissionStoreHook() { return usePermissionStore(store); }二、在注册动态路(router.addRoute)由之前处理路由数据/** * 将三级路由扁平化为二级路由 * param {Array} routes - 原始的三级路由树 * returns {Array} - 扁平化后的路由数组 */ function flattenThreeLevelRoutes(routes: any[]) { const result []; for (const level1Route of routes) { // 保留一级路由的基本信息 const flatLevel1Route { ...level1Route, children: [] }; if (level1Route.children level1Route.children.length 0) { for (const level2Route of level1Route.children) { // 处理二级路由的children三级路由 if (level2Route.children level2Route.children.length 0) { // 将三级路由提升为二级路由 for (const level3Route of level2Route.children) { // console.log(三级路由,level3Route) flatLevel1Route.children.push({ ...level3Route }); } } else { // 二级路由没有children直接保留 flatLevel1Route.children.push(level2Route); } } } result.push(flatLevel1Route); } return result; } const { accessibleModuleList } await userStore.getInfo(); //下传前端的菜单权限等数据 const accessRoutes await permissionStore.generateRoutes(accessibleModuleList); console.log(原始路由数据, accessRoutes); // 关键步骤将三级路由扁平化为二级 const flatRoutes flattenThreeLevelRoutes(accessRoutes); console.log(扁平化后的路由数据, flatRoutes); flatRoutes.forEach((route) { router.addRoute(route); });通过上面的关键步骤我的项目已经可以实现三级路由缓存的效果了三、面包屑导航问题处理我的项目中去掉了面包屑导航这个鸡肋的功能原有的面包屑导航是通过$route.matched可以获取到嵌套路由每一层级的信息而当路由被处理成两级后也就无法通过$route.matched进行显示了所以在处理路由数据的同时也需要处理面包屑导航的信息。大致最终会处理成这样{ path: /users, meta: { title: 用户管理 }, children: [ { path: clients/list, meta: { title: 客户列表, breadCrumb: [ { path: /users, title: 用户管理 }, { path: clients, title: 客户管理 }, { path: list, title: 客户列表 } ] } }, { path: clients/detail, meta: { title: 客户详情, breadCrumb: [ { path: /users, title: 用户管理 }, { path: clients, title: 客户管理 }, { path: detail, title: 客户详情 } ] } } ] }这样一来通过$route.meta.breadcrumb也就可以获取任意某个路由的完整面包屑导航信息了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询