import { asyncRouterHandle } from '@/utils/asyncRouter' import { emitter } from '@/utils/bus.js' import { asyncMenu } from '@/api/menu' import { defineStore } from 'pinia' import { ref } from 'vue' const notLayoutRouterArr = [] const keepAliveRoutersArr = [] const nameMap = {} // 递归拼接parent Path 返回path const formatParentPath = (parent) => { let parentPath = '' if (parent) { parentPath = formatParentPath(parent.parent) parentPath += parent.path } return parentPath } const formatRouter = (routes, routeMap, parent) => { routes && routes.forEach(item => { item.parent = parent item.meta.btns = item.btns item.meta.hidden = item.hidden if (item.meta.defaultMenu === true) { const parentPath = formatParentPath(parent) item = { ...item, path: `${parentPath}/${item.path}` } notLayoutRouterArr.push(item) } routeMap[item.name] = item if (item.children && item.children.length > 0) { formatRouter(item.children, routeMap, item) } }) } const KeepAliveFilter = (routes) => { routes && routes.forEach(item => { // 子菜单中有 keep-alive 的,父菜单也必须 keep-alive,否则无效。这里将子菜单中有 keep-alive 的父菜单也加入。 if ((item.children && item.children.some(ch => ch.meta.keepAlive) || item.meta.keepAlive)) { item.component && item.component().then(val => { keepAliveRoutersArr.push(val.default.name) nameMap[item.name] = val.default.name }) } if (item.children && item.children.length > 0) { KeepAliveFilter(item.children) } }) } export const useRouterStore = defineStore('router', () => { const keepAliveRouters = ref([]) const asyncRouterFlag = ref(0) const setKeepAliveRouters = (history) => { const keepArrTemp = [] history.forEach(item => { if (nameMap[item.name]) { keepArrTemp.push(nameMap[item.name]) } }) keepAliveRouters.value = Array.from(new Set(keepArrTemp)) } emitter.on('setKeepAlive', setKeepAliveRouters) const asyncRouters = ref([]) const routeMap = ({}) // 从后台获取动态路由 const SetAsyncRouter = async() => { asyncRouterFlag.value++ const baseRouter = [{ path: '/layout', name: 'layout', component: 'view/layout/index.vue', meta: { title: '底层layout' }, children: [] }] const asyncRouterRes = await asyncMenu() const asyncRouter = asyncRouterRes.data.menus asyncRouter && asyncRouter.push({ path: 'reload', name: 'Reload', hidden: true, meta: { title: '', closeTab: true, }, component: 'view/error/reload.vue' }) formatRouter(asyncRouter, routeMap) baseRouter[0].children = asyncRouter if (notLayoutRouterArr.length !== 0) { console.log(notLayoutRouterArr) baseRouter.push(...notLayoutRouterArr) } asyncRouterHandle(baseRouter) KeepAliveFilter(asyncRouter) asyncRouters.value = baseRouter return true } return { asyncRouters, keepAliveRouters, asyncRouterFlag, SetAsyncRouter, routeMap } })