162 lines
4.8 KiB
Vue
162 lines
4.8 KiB
Vue
<template>
|
|
<div class="layout-navbars-breadcrumb-index" :class="setBreadcrumbStyle">
|
|
<div class="left-section">
|
|
<Logo v-if="setIsShowLogo" />
|
|
</div>
|
|
<Horizontal :menuList="state.menuList" />
|
|
<div class="right-section">
|
|
<User />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="layoutBreadcrumbIndex">
|
|
import { defineAsyncComponent, computed, reactive, onMounted, onUnmounted, onBeforeMount } from 'vue'
|
|
import { useRoute, useRouter, RouteRecordRaw } from 'vue-router'
|
|
import { storeToRefs } from 'pinia'
|
|
import { useRoutesList } from '/@/stores/routesList'
|
|
import { useThemeConfig } from '/@/stores/themeConfig'
|
|
import mittBus from '/@/utils/mitt'
|
|
import { treeToList, listToTree, filterList } from '/@/utils/tree'
|
|
import { cloneDeep } from 'lodash-es'
|
|
|
|
// 引入组件
|
|
const User = defineAsyncComponent(() => import('/@/layout/navBars/topBar/user.vue'))
|
|
const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue'))
|
|
const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue'))
|
|
|
|
// 支持 props 传递 menuList
|
|
const props = defineProps<{
|
|
menuList?: RouteItems
|
|
}>()
|
|
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
const stores = useRoutesList()
|
|
const storesThemeConfig = useThemeConfig()
|
|
const { routesList } = storeToRefs(stores)
|
|
const { themeConfig } = storeToRefs(storesThemeConfig)
|
|
const state = reactive({
|
|
menuList: [] as RouteItems,
|
|
})
|
|
|
|
const setBreadcrumbStyle = computed(() => {
|
|
const { topBar } = themeConfig.value
|
|
const bgTheme = ['#FFFFFF', '#FFF', '#fff', '#ffffff']
|
|
return [bgTheme.includes(topBar) ? '' : 'layout-navbars-breadcrumb-index-no-bb']
|
|
})
|
|
|
|
// 设置 logo 显示/隐藏
|
|
const setIsShowLogo = computed(() => {
|
|
let { isShowLogo, layout } = themeConfig.value
|
|
return (isShowLogo && layout === 'classic') || (isShowLogo && layout === 'transverse')
|
|
})
|
|
|
|
// 设置/过滤路由(非静态路由/是否显示在菜单中)
|
|
const setFilterRoutes = () => {
|
|
let { layout, isClassicSplitMenu } = themeConfig.value
|
|
if (layout === 'classic' && isClassicSplitMenu) {
|
|
// 为了支持下拉菜单,我们保留完整的菜单结构给 horizontal 组件
|
|
// 但仍然发送分割后的数据给侧边栏
|
|
state.menuList = filterRoutesFun(routesList.value) // 保留完整结构用于下拉菜单
|
|
const resData = setSendClassicChildren(route.path)
|
|
//console.log('设置/过滤路由', resData)
|
|
//mittBus.emit('setSendClassicChildren', resData)
|
|
} else {
|
|
state.menuList = filterRoutesFun(routesList.value)
|
|
}
|
|
}
|
|
|
|
// 路由过滤递归函数
|
|
const filterRoutesFun = <T extends RouteItem>(arr: T[]): T[] => {
|
|
return arr
|
|
.filter((item: T) => !item.meta?.isHide)
|
|
.map((item: T) => {
|
|
item = Object.assign({}, item)
|
|
// 恢复子菜单数据处理,支持下拉菜单功能
|
|
if (item.children) item.children = filterRoutesFun(item.children)
|
|
return item
|
|
})
|
|
}
|
|
|
|
const getRootPath = (path: string) => {
|
|
let rootPath = ''
|
|
let routeTree = listToTree(
|
|
filterList(treeToList(cloneDeep(routesList.value)), path, {
|
|
filterWhere: (item: any, filterword: string) => {
|
|
return item.path?.toLocaleLowerCase() === filterword
|
|
},
|
|
})
|
|
)
|
|
if (routeTree.length > 0 && routeTree[0]?.path) {
|
|
rootPath = routeTree[0].path
|
|
}
|
|
return rootPath
|
|
}
|
|
|
|
// 新增:传送当前二级子级数据到左侧菜单
|
|
const setSendClassicChildren = (path: string) => {
|
|
let res: MittMenu = { children: [] }
|
|
|
|
//解析菜单路径
|
|
const rootPath = getRootPath(path)
|
|
const module = state.menuList.find(item => item.path === rootPath)
|
|
if (module && module.children) {
|
|
const sub = module.children.find((child: RouteRecordRaw) => path.startsWith(child.path))
|
|
if (sub) {
|
|
res.item = { ...sub }
|
|
res.children = sub.children ? [...sub.children] : []
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
// 页面加载时
|
|
onMounted(() => {
|
|
setFilterRoutes()
|
|
if (themeConfig.value.layout === 'classic' && themeConfig.value.isClassicSplitMenu) {
|
|
mittBus.emit('setSendClassicChildren', setSendClassicChildren(route.path))
|
|
}
|
|
})
|
|
// 页面卸载时
|
|
onUnmounted(() => {
|
|
mittBus.off('getBreadcrumbIndexSetFilterRoutes', () => {})
|
|
})
|
|
|
|
onBeforeMount(() => {
|
|
if (themeConfig.value.layout === 'classic' && themeConfig.value.isClassicSplitMenu) {
|
|
//console.log('onBeforeMount11122', route.path)
|
|
//mittBus.emit('setSendClassicChildren', route.path)
|
|
}
|
|
})
|
|
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.layout-navbars-breadcrumb-index {
|
|
height: 50px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background: var(--next-bg-topBar);
|
|
border-bottom: 1px solid var(--next-border-color-light);
|
|
|
|
.left-section {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.right-section {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
margin-right: 16px;
|
|
}
|
|
}
|
|
|
|
.layout-navbars-breadcrumb-index-no-bb {
|
|
border-bottom-width: 0px;
|
|
}
|
|
</style>
|