框架修改思路

一、组件引入基本样式

面包屑(使用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 函数,从会话存储中获取菜单数据。

综上所述,这段代码实现了从会话存储中获取菜单数据,根据菜单点击动态创建和切换标签页,以及路由导航的功能

相关推荐
庸俗今天不摸鱼18 分钟前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX1873019 分钟前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下25 分钟前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox36 分钟前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞39 分钟前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行39 分钟前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_5937581040 分钟前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox
掘金一周43 分钟前
金石焕新程 >> 瓜分万元现金大奖征文活动即将回归 | 掘金一周 4.3
前端·人工智能·后端
三翼鸟数字化技术团队1 小时前
Vue自定义指令最佳实践教程
前端·vue.js
Jasmin Tin Wei2 小时前
蓝桥杯 web 学海无涯(axios、ecahrts)版本二
前端·蓝桥杯