mart-admin/src/layout/navMenu/vertical.vue
2025-01-06 12:21:01 +08:00

166 lines
5.0 KiB
Vue
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.

<template>
<el-menu
router
:default-active="state.defaultActive"
background-color="transparent"
:collapse="state.isCollapse"
:unique-opened="getThemeConfig.isUniqueOpened"
:collapse-transition="false"
:default-openeds="defaultOpeneds"
>
<!-- <template v-for="val in menuLists">
<el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<template #title>
<SvgIcon :name="val.meta.icon" />
<span>{{ $t(val.meta.title) }}</span>
</template>
<SubItem :chil="val.children" />
</el-sub-menu>
<template v-else>
<el-menu-item :index="val.path" :key="val.path">
<SvgIcon :name="val.meta.icon" />
<template #title v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
<span>{{ $t(val.meta.title) }}</span>
</template>
<template #title v-else>
<a class="w100" @click.prevent="onALinkClick(val)">{{ $t(val.meta.title) }}</a>
</template>
</el-menu-item>
</template>
</template> -->
<el-sub-menu :index="index.toString()" v-for="(item,index) in menuLists" :key="index" >
<template #title>
<span>{{ item.modulename }}</span>
</template>
<el-menu-item-group>
<font-awesome-icon :icon="['fas',item.actions[0].icon]" size="lg" class="edtIcon" />
<el-menu-item :index="item1.link" v-for="(item1, index1) in item.actions" :key="index1">
<SvgIcon :name="item1.icon" />
{{ item1.actionname }}
</el-menu-item>
</el-menu-item-group>
</el-sub-menu>
</el-menu>
</template>
<script setup lang="ts" name="navMenuVertical">
import { defineAsyncComponent, reactive, computed, onMounted, watch,ref ,onBeforeMount} from 'vue';
import { useRoute, onBeforeRouteUpdate, RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import other from '/@/utils/other';
import {useMenuApi} from '/@/api/menu'
// 引入组件
const SubItem = defineAsyncComponent(() => import('/@/layout/navMenu/subItem.vue'));
// 定义父组件传过来的值
const props = defineProps({
// 菜单列表
menuList: {
type: Array<RouteRecordRaw>,
default: () => [],
},
});
// 定义变量内容
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
const route = useRoute();
const state = reactive({
// 修复https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
defaultActive: route.meta.isDynamic ? route.meta.isDynamicPath : route.path,
isCollapse: false,
});
// 获取父级菜单数据
const menuLists = computed(() => {
return props.menuList || [];
});
// 获取布局配置信息
const getThemeConfig = computed(() => {
return themeConfig.value;
});
// 默认全展开的实现
// const defaultOpeneds = computed(() => {
// if (menuLists.value.length === 0) {
// console.log(111111111111);
// return []; // 没有菜单时返回空数组
// }
// console.log(22222222222);
// return menuLists.value.map((_, index) => index.toString());
// });
const defaultOpeneds = ref<string[]>([]);
// 菜单高亮(详情时,父级高亮)
const setParentHighlight = (currentRoute: RouteToFrom) => {
const { path, meta } = currentRoute;
const pathSplit = meta?.isDynamic ? meta.isDynamicPath!.split('/') : path!.split('/');
if (pathSplit.length >= 4 && meta?.isHide) return pathSplit.splice(0, 3).join('/');
else return path;
};
// 打开外部链接
const onALinkClick = (val: RouteItem) => {
other.handleOpenLink(val);
};
// 页面加载时
onMounted(() => {
state.defaultActive = setParentHighlight(route);
// 每次加载页面,初始化默认展开项
// const storedOpeneds = localStorage.getItem('defaultOpeneds');
// if (storedOpeneds) {
// console.log('Loaded from localStorage:', JSON.parse(storedOpeneds));
// } else {
// // 如果没有存储记录,设置为全部展开
// localStorage.setItem('defaultOpeneds', JSON.stringify(defaultOpeneds.value));
// }
});
// 路由更新时
onBeforeRouteUpdate((to) => {
// 修复https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
state.defaultActive = setParentHighlight(to);
const clientWidth = document.body.clientWidth;
if (clientWidth < 1000) themeConfig.value.isCollapse = false;
});
// 设置菜单的收起/展开
watch(
() => themeConfig.value.isCollapse,
(isCollapse) => {
document.body.clientWidth <= 1000 ? (state.isCollapse = false) : (state.isCollapse = isCollapse);
},
{
immediate: true,
}
);
// // 监听默认展开状态,并存储到 localStorage
// // 保存状态到 localStorage每次更改时更新存储
// watch(defaultOpeneds, (newVal) => {
// localStorage.setItem('defaultOpeneds', JSON.stringify(newVal));
// });
// 监控 props 的变化,确保 defaultOpeneds 始终正确
watch(
() => props.menuList,
(newMenuList) => {
defaultOpeneds.value = newMenuList.map((_, index) => index.toString());
},
{
immediate: true,
deep: true,
}
);
</script>
<style lang="scss" scoped>
::v-deep .el-menu-item-group__title{
padding :0px 0px 0px ;
}
</style>