江苏建设人才网官网入口,seo最好的工具,截获网站流量怎么做,域名购买网后台管理 1. 动态路由2. 动态侧边栏菜单 持续更新中。。。
1. 动态路由 后台路由模型数据 #xff08;如果后端不知道怎么转为 这种树结构的路由#xff0c;可以参考 普通数组转树结构的数组#xff09; const dynamicRoutes [{path: /,name: Layout,redirect: /home,comp… 后台管理 1. 动态路由2. 动态侧边栏菜单 持续更新中。。。
1. 动态路由 后台路由模型数据 如果后端不知道怎么转为 这种树结构的路由可以参考 普通数组转树结构的数组 const dynamicRoutes [{path: /,name: Layout,redirect: /home,component: Layout,meta: {label: ,icon: ,hidden: false,},children: [{path: /home,name: Home,component: Home,meta: {label: 首页,icon: HomeFilled,hidden: false}},]},{path: /perm,name: perm,component: Layout,redirect: /perm/user,meta: {label: 权限管理,icon: Lock,hidden: false},children: [{path: /perm/user,name: user,component: User,meta: {label: 用户管理,icon: User,hidden: false},},{path: /perm/role,name: role,component: Role,meta: {label: 角色管理,icon: Avatar,hidden: false},},{path: /perm/menu,name: permMenu,component: PermMenu,meta: {label: 菜单管理,icon: Grid,hidden: false},},]},// 这个路由不能放到常量路由里面必须放到动态路由// 原因在刷新页面时动态路由丢失需要重新加载动态路由// 因为当前还没有动态路由只能重定向到404// 所以即使后面动态路由加载成功也不会再去重定向到 动态路由{path: /:pathMatcher(.*)*,redirect: /404,name: any,meta: {label: ,icon: ,hidden: true}},]后台路由模型 转 前端需要的路由对象 2.1 准备前端组件信息。这相当于是一个Map在下面 转换 的时候会用到。 import Layout from /layout/index.vue
import Home from /views/home/index.vue
import Screen from /views/screen/index.vue
import User from /views/perm/user/index.vue
import Role from /views/perm/role/index.vue
import PermMenu from /views/perm/menu/index.vueexport const allRouteComponents {Layout,Home,Screen,User,Role,PermMenu,
}2.2 转换操作 // 将后端获取到的动态路由 添加到 router
// 在路由守卫中使用刷新页面时重新添加动态路由解决内存中路由丢失白屏问题
// 这里传入的路由数组就是后端传过来的
const addRoutes (routesArr) {const routesObjArr convertRoutes(routesArr)routesObjArr.forEach(item {router.addRoute(item)})
}// 将后端获取到的路由对象的 component字符串类型 转为 component组件对象
const convertRoutes (routesArr) {return routesArr.map(item {let routeObj allRouteComponents[item.component]if (routeObj) {item.component routeObj}if (item.children) {item.children convertRoutes(item.children)}return item})
}动态路由添加 addRoutes() const userStore useUserStore() const menuStore useMenuStore() 仓库函数的使用要写在 路由守卫里面写在外面会报pinia没有激活错误。 原因 1、 在项目启动时仓库可能还没有被use肯定会报错 2、 如果写在路由守卫里面只有在切换路由的时候才会使用到仓库这个时候仓库肯定已经被use了。 registerFlag 每次刷新页面这个值都会重新初始化为false内存中路由也被清除。这个就需要重新添加 routes。添加routes后registerFlag 置为 true。再执行路由切换不需要重复添加只有刷新才会重新触发 // 刷新页面时重新添加动态路由
const registerFlag ref(false)router.beforeEach(async (to, from, next) {const userStore useUserStore()const menuStore useMenuStore()// 判断用户是否登录if (userStore.token) {// 解决刷新页面内存中路由丢失问题if (!registerFlag.value) {addRoutes(menuStore.userMenus)registerFlag.value true// 添加完路由重新访问目标页面await router.replace(to)}// 已经登录访问/login,会重定向到 / (首页)if (to.path /login) {next(/home)} else {next()}} else {// 未登录if (to.path /login) {next()} else {// 重定向到/login,并追加一个 登录成功后重定向地址next({path: /login, query: {redirect: to.path}})}}
})2. 动态侧边栏菜单 后端数据模型 const dynamicRoutes [{path: /,name: Layout,redirect: /home,component: Layout,meta: {label: ,icon: ,hidden: false,},children: [{path: /home,name: Home,component: Home,meta: {label: 首页,icon: HomeFilled,hidden: false}},]},{path: /perm,name: perm,component: Layout,redirect: /perm/user,meta: {label: 权限管理,icon: Lock,hidden: false},children: [{path: /perm/user,name: user,component: User,meta: {label: 用户管理,icon: User,hidden: false},},{path: /perm/role,name: role,component: Role,meta: {label: 角色管理,icon: Avatar,hidden: false},},{path: /perm/menu,name: permMenu,component: PermMenu,meta: {label: 菜单管理,icon: Grid,hidden: false},},]},// 这个路由不能放到常量路由里面必须放到动态路由// 原因在刷新页面时动态路由丢失需要重新加载动态路由// 因为当前还没有动态路由只能重定向到404// 所以即使后面动态路由加载成功也不会再去重定向到 动态路由{path: /:pathMatcher(.*)*,redirect: /404,name: any,meta: {label: ,icon: ,hidden: true}},
]后端路由数据–过滤出hiddenfalse用于侧边栏展示的 script setup
import AsideMenu from /layout/menu/index.vue
import {computed,defineOptions} from vue;
defineOptions({name: Layout})// 去 hidden 函数
// 如果父路由 隐藏那么子路由hidden不论truefalse都不会显示
// 如果父路由 显示那么子路由hidden为false会显示hidden为true会隐藏
const filterHiddenRoute (routes) {return routes.filter(item {if (!item.meta.hidden) {if (item.children) {item.children filterHiddenRoute(item.children)}return true} else {return false}})
}
// 去掉hidden后的菜单树
// 这里传入的routes就是后端传来的路由数组树结构
const menuList computed(() {return filterHiddenRoute(routes)
})
/script
templateel-menuaside-menu :menuListmenuList/aside-menu/el-menu
/template动态菜单递归组件定义 递归菜单必须有组件名用于在组件中调用自身 script setup
import router from /routerdefineOptions({name: AsideMenu})
const menus defineProps([menuList])// 跳转路由
const goRoute (e) {router.push(e.index)
}
/scripttemplatetemplate v-foritem of menus.menuList :keyitem.path!-- 没有子菜单--el-menu-item v-if!item.children :indexitem.path clickgoRouteel-iconcomponent :isitem.meta.icon/component/el-icontemplate #titlespan{{ item.meta.label }}/span/template/el-menu-item!-- 有子菜单但是只有1个--el-menu-item v-ifitem.children item.children.length1 :indexitem.children[0].path clickgoRouteel-iconcomponent :isitem.children[0].meta.icon/component/el-icontemplate #titlespan{{ item.children[0].meta.label }}/span/template/el-menu-item!-- 有子菜单子菜单大于1个--el-sub-menu v-ifitem.children item.children.length1 :indexitem.pathtemplate #titleel-iconcomponent :isitem.meta.icon/component/el-iconspan{{ item.meta.label }}/span/templateAsideMenu :menuListitem.children/AsideMenu/el-sub-menu/template
/template
style scoped langscss
/style