框架修改思路

发布于:2025-04-01 ⋅ 阅读:(14) ⋅ 点赞:(0)

一、组件引入基本样式

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

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