1. 第一步:登录步骤就不多说了,调用获取动态路由接口将返回的动态路由数据通过pinia的setAsideRoutes方法保存用于渲染侧边菜单栏用,获取到动态路由数据的第一步也是要先保存到本地一份的 (pinia浏览器刷新状态会重置,到时可以从缓存读取),在这一步也可以顺带序列化动态路由数据,将本地组件映射到路由数据中并通过addRoute方法逐一添加
import { ref, computed, reactive } from 'vue'
import { defineStore } from 'pinia'
import map from "@/router/map.js"
import dynamicRouters from '@/router/dynamicRouters.js'
import router from '@/router/index.js'
export const useAppStore = defineStore('app', () => {
const isCollapse = ref(false)
const activePath = ref('/')
const asideRoutes = ref([]) // 全局权限侧边菜单栏
const formatAddRoutes = routes => {
routes.forEach(item => {
let routeName = item.component
console.log('formatAddRoutes:',item.component,map[item.component])
item.component = map[item.component]
if (item.component === undefined) {
ElMessage.error(`组件【${routeName}】加载失败`)
}
if (item?.children?.length) {
formatAddRoutes(item.children)
}
router.addRoute(item)
})
}
return {
isCollapse,
activePath,
asideRoutes,
setCollapse: _ => isCollapse.value = !isCollapse.value,
setActivePath: path => activePath.value = path,
setAsideRoutes: routes => {
asideRoutes.value = routes || JSON.parse(localStorage.getItem('asideRoutes') || '[]')
localStorage.setItem('asideRoutes', JSON.stringify(asideRoutes.value))
formatAddRoutes(asideRoutes.value)
},
}
})
2. 需要在前置路由 beforeEach 中做拦截操作,代码很简单,需要设置一个标识,只要每次刷新浏览器或手动输入路由地址,这里的flag就会默认为true,调用pinia内部设置菜单路由方法重新添加动态路由
import { useAppStore } from '@/stores/app.js'
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/login',
name: 'login',
component: _ => import( /* webpackChunkName: "test" */ '@/views/login/index.vue')
},
{
path: '/:catchAll(.*)',
name: 'error',
component: _ => import( /* webpackChunkName: "test" */ '@/views/error/index.vue')
}
]
})
let flag = true // 解决动态路由刷新消失的问题
router.beforeEach((to,form,next) => {
const appStore = useAppStore()
appStore.setActivePath(to.fullPath)
if(flag) {
flag = false
appStore.setAsideRoutes()
next({path: to.fullPath}) // 这段代码很诡异,去掉后动态路由刷新就失效
}
next()
})
export default router