一、组件引入基本样式
面包屑(使用element plus的标签页)
<!-- 标签页区域 -->
<el-tabs v-model="activeTab" type="card" closable @tab-remove="removeTab" class="top-tabs">
<el-tab-pane
:key="tab.name"
:label="tab.title"
:name="tab.name"
v-for="tab in tabs"
>
<div class="tab-content-placeholder">
{{ tab.content }}
</div>
</el-tab-pane>
</el-tabs>
菜单容器
<!-- 菜单容器 -->
<div class="menu-wrapper">
<!-- 折叠按钮区域 -->
<div class="radio-group-container">
<el-radio-group v-model="isCollapse" style="margin-bottom: 0;">
<div :class="['icon-background', { 'collapsed': isCollapse }]">
<el-icon :size="25" :color="isCollapse? 'white' : '#ffd04b'" @click="isCollapse =!isCollapse"
style="margin-top: 10px;margin-left: 10px;">
<component :is="isCollapse? Expand : Fold" />
</el-icon>
</div>
</el-radio-group>
</div>
<!-- 主菜单区域 -->
<el-menu
router
default-active="Login"
class="full-height-menu dark-menu"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
background-color="#001529"
text-color="#bfcbd9"
active-text-color="#409EFF"
style="margin-top: -10px;"
@select="handleMenuSelect"
>
<template v-for="item in dynamicMenuItems" :key="item.path">
<template v-if="item.children && item.children.length > 0">
<el-sub-menu :index="item.path">
<template #title>
<el-icon>
<component :is="item.meta.icon" v-if="item.meta.icon" />
</el-icon>
<span>{{ item.meta.title }}</span>
</template>
<template v-for="child in item.children" :key="child.path">
<el-menu-item :index="child.path">
<el-icon>
<component :is="child.meta.icon" v-if="child.meta.icon" />
</el-icon>
<span>{{ child.meta.title }}</span>
</el-menu-item>
</template>
</el-sub-menu>
</template>
<el-menu-item v-else :index="item.path">
<el-icon>
<component :is="item.meta.icon" v-if="item.meta.icon" />
</el-icon>
<span>{{ item.meta.title }}</span>
</el-menu-item>
</template>
</el-menu>
</div>
二.实现思路
1.导入必要的模块和组件
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import {
ElRadioGroup,
ElMenu,
ElMenuItem,
ElIcon,
ElSubMenu,
ElTabs,
ElTabPane
} from 'element-plus';
import {
Expand,
Fold
} from '@element-plus/icons-vue';
2. 定义响应式数据
const router = useRouter();
const isCollapse = ref(true);
const dynamicMenuItems = ref([]);
const activeTab = ref('');
const tabs = ref([]);
3. 获取本地存储的菜单数据
const getDynamicMenuItems = () => {
const storedMenuPath = sessionStorage.getItem('menuPath');
if (storedMenuPath) {
const menuPathData = JSON.parse(storedMenuPath);
dynamicMenuItems.value = menuPathData.map(item => {
const menuItem = {
path: item.path,
meta: {
title: item.name,
icon: null
}
};
if (item.children && item.children.length > 0) {
menuItem.children = item.children.map(child => ({
path: child.path,
meta: {
title: child.name,
icon: null
}
}));
}
return menuItem;
});
}
};
4. 查找菜单项及其所有子项的完整路径
const findAllMenuPaths = (items) => {
const paths = [];
items.forEach(item => {
paths.push(item.path);
if (item.children) {
paths.push(...findAllMenuPaths(item.children));
}
});
return paths;
};
5. 菜单点击事件处理
const handleMenuSelect = (key) => {
const allPaths = findAllMenuPaths(dynamicMenuItems.value);
if (!allPaths.includes(key)) return;
const existingTab = tabs.value.find(tab => tab.name === key);
const menuItem = findMenuItemByPath(key);
if (menuItem) {
if (existingTab) {
activeTab.value = key;
} else {
const newTab = {
name: key,
title: menuItem.meta.title,
content: `${menuItem.meta.title} 内容区域`
};
tabs.value.push(newTab);
activeTab.value = key;
}
// 导航到对应路由
router.push(key);
}
};
6. 根据路径查找菜单项
const findMenuItemByPath = (path, items = dynamicMenuItems.value) => {
for (const item of items) {
if (item.path === path) return item;
if (item.children) {
const found = findMenuItemByPath(path, item.children);
if (found) return found;
}
}
return null;
};
7. 处理标签页关闭事件
const removeTab = (targetName) => {
tabs.value = tabs.value.filter(tab => tab.name !== targetName);
if (activeTab.value === targetName) {
activeTab.value = tabs.value.length > 0 ? tabs.value[0].name : '';
}
};
8. 处理菜单展开和关闭事件
const handleOpen = (key, keyPath) => {
console.log('菜单展开:', key, keyPath);
};
const handleClose = (key, keyPath) => {
console.log('菜单关闭:', key, keyPath);
};
9. 组件挂载后执行的操作
onMounted(() => {
getDynamicMenuItems();
});
onMounted
是一个生命周期钩子函数,在组件挂载后执行。- 调用
getDynamicMenuItems
函数,从会话存储中获取菜单数据。
综上所述,这段代码实现了从会话存储中获取菜单数据,根据菜单点击动态创建和切换标签页,以及路由导航的功能