import { asyncRouterHandle } from '@/utils/asyncRouter' import { emitter } from '@/utils/bus.js' import { asyncMenu } from '@/api/menu' import { defineStore } from 'pinia' import { ref,watchEffect,onMounted } from 'vue' const notLayoutRouterArr = [] const keepAliveRoutersArr = [] const nameMap = {} 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) { if (!parent) { item = { ...item, path: `/${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 topMenu = ref([]) const leftMenu = ref([]) const menuMap = {} const topActive = ref("") const setLeftMenu = (name) => { sessionStorage.setItem('topActive', name) topActive.value = name if(menuMap[name]?.children){ leftMenu.value = menuMap[name].children } return menuMap[name]?.children } watchEffect(()=>{ let topActive = sessionStorage.getItem("topActive") let firstHasChildren = '' asyncRouters.value[0]?.children.forEach((item) => { if (item.hidden) return; menuMap[item.name] = item; if (!firstHasChildren && item.children && item.children.length > 0) { firstHasChildren = item.name } topMenu.value.push({...item, children: []}) }); if(!menuMap[topActive]?.children && firstHasChildren){ topActive = firstHasChildren } setLeftMenu(topActive) }) 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) { baseRouter.push(...notLayoutRouterArr) } asyncRouterHandle(baseRouter) KeepAliveFilter(asyncRouter) asyncRouters.value = baseRouter return true } return { topActive, setLeftMenu, topMenu, leftMenu, asyncRouters, keepAliveRouters, asyncRouterFlag, SetAsyncRouter, routeMap } })