Files
gin-vue-admin-stu/web/src/pinia/modules/router.js
2025-11-09 16:15:22 +08:00

185 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { asyncRouterHandle } from '@/utils/asyncRouter'
import { emitter } from '@/utils/bus.js'
import { asyncMenu } from '@/api/menu'
import { defineStore } from 'pinia'
import { ref, watchEffect } from 'vue'
import pathInfo from '@/pathInfo.json'
import {useRoute} from "vue-router";
import {config} from "@/core/config.js";
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
) {
const path = item.meta.path
keepAliveRoutersArr.push(pathInfo[path])
nameMap[item.name] = pathInfo[path]
}
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 = []
// 1. 首先添加原有的keepAlive配置
keepArrTemp.push(...keepAliveRoutersArr)
if (config.keepAliveTabs) {
history.forEach((item) => {
// 2. 为所有history中的路由强制启用keep-alive
// 通过routeMap获取路由信息然后通过pathInfo获取组件名
const routeInfo = routeMap[item.name]
if (routeInfo && routeInfo.meta && routeInfo.meta.path) {
const componentName = pathInfo[routeInfo.meta.path]
if (componentName) {
keepArrTemp.push(componentName)
}
}
// 3. 如果子路由在tabs中打开父路由也需要keepAlive
if (nameMap[item.name]) {
keepArrTemp.push(nameMap[item.name])
}
})
}
keepAliveRouters.value = Array.from(new Set(keepArrTemp))
}
const route = useRoute()
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
leftMenu.value = []
if (menuMap[name]?.children) {
leftMenu.value = menuMap[name].children
}
return menuMap[name]?.children
}
const findTopActive = (menuMap, routeName) => {
for (let topName in menuMap) {
const topItem = menuMap[topName];
if (topItem.children?.some(item => item.name === routeName)) {
return topName;
}
const foundName = findTopActive(topItem.children || {}, routeName);
if (foundName) {
return topName;
}
}
return null;
};
watchEffect(() => {
let topActive = sessionStorage.getItem('topActive')
// 初始化菜单内容,防止重复添加
topMenu.value = [];
asyncRouters.value[0]?.children.forEach((item) => {
if (item.hidden) return
menuMap[item.name] = item
topMenu.value.push({ ...item, children: [] })
})
if (!topActive || topActive === 'undefined' || topActive === 'null') {
topActive = findTopActive(menuMap, route.name);
}
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
}
})