14、springboot3 vue3开发平台-前端-自定义菜单组件,根据路由动态渲染

文章目录

  • [1. 组件](#1. 组件)
  • [2 . 使用示例](#2 . 使用示例)

1. 组件

src\components\menuTree\index.vue

c 复制代码
<template>
    <template v-for="item in menuList">
        <!-- 分为两种方式渲染:有子菜单和没有子菜单-->
        <!--      没有子菜单-->
        <el-menu-item :index="item.path" v-if="item.children.length == 0" :key="item.path"
            @click="handleRouter(item)">
            <el-icon v-if="item.icon"><svg-icon slot="prefix" :name="item.icon" width="18px" height="18px" /></el-icon>
            <span>{{ item.menuName }}</span>
        </el-menu-item>

        <el-sub-menu :index="item.path" v-if="item?.children?.length > 0" >
            <template #title>
                <el-icon v-if="item.icon"><svg-icon slot="prefix" :name="item.icon" width="18px" height="18px" /></el-icon>
                <span @click="handleSubMenu($event, item)">{{ item.menuName }}</span>
            </template>
            <!--        有子菜单的继续遍历(递归)-->
            <MenuTree :menuList="item.children" ></MenuTree>
        </el-sub-menu>
    </template>
</template>
<script setup lang="ts" >
// 声明 props - 对象格式  在script 中不使用props拿不到数据, <template>中自动解构

const props = defineProps({
    menuList: Array<any>
})

// 定义要触发的事件  
const emit = defineEmits(['childEvent'])

// 切换路由
const handleRouter = (menu: any) => {
    emit('childEvent', { type: 'menuItem', item: menu })
}

// 目录被点击
const handleSubMenu = (event: Event, menu: any) => {
    let event1 = event.currentTarget
    let event2 = event.target
    if (event1 == event2) {
        emit('childEvent', { type: 'subMenu', item: menu })
    }
}

</script>
<script>
export default {
    name: "MenuTree"
}
</script>

注1: 组件自递归要使用时要导出

注2: 这里使用的图标是之前自定义的图标组件

c 复制代码
<script>
export default {
    name: "MenuTree"
}
</script>

2 . 使用示例

在父组件中:

c 复制代码
<MenuTree :menuList="menuList" @childEvent="handChildEvent"></MenuTree>

// 获取pinia的缓存的菜单数据, 这里数据来源根据自己实际来获取
const menuList = menuStore.menuList

// 子组件事件逻辑根据实际来定义
const handChildEvent = (data: any) => {
    let menu = data.item
    if (data.type == 'menuItem') {
        // 向tabList中添加数据,检查是否已经添加  数据结构:{title:'首页',path:'/index'}
        let hasNode = menuStore.tabList.filter((item: any) => item.path == menu.path)
        if (hasNode == null || hasNode.length == 0) {
            let data = { title: menu.menuName, path: menu.path, id: menu.id, menuName: menu.menuName, parentId: menu.parentId }
            menuStore.setTabList(data)
        }
        // 修改activeTab的值
        menuStore.setActive(menu.path)
        // 缓存面包屑数据
        menuStore.addBreadList(menu)
    } 
    if (data.type == 'subMenu') {
        menuStore.addBreadList(menu)
    }
}
相关推荐
李鸿耀12 分钟前
仅用几行 CSS,实现优雅的渐变边框效果
前端
码事漫谈31 分钟前
解决 Anki 启动器下载错误的完整指南
前端
im_AMBER1 小时前
Web 开发 27
前端·javascript·笔记·后端·学习·web
蓝胖子的多啦A梦1 小时前
低版本Chrome导致弹框无法滚动的解决方案
前端·css·html·chrome浏览器·版本不同造成问题·弹框页面无法滚动
玩代码1 小时前
vue项目安装chromedriver超时解决办法
前端·javascript·vue.js
訾博ZiBo2 小时前
React 状态管理中的循环更新陷阱与解决方案
前端
StarPrayers.2 小时前
旅行商问题(TSP)(2)(heuristics.py)(TSP 的两种贪心启发式算法实现)
前端·人工智能·python·算法·pycharm·启发式算法
一壶浊酒..2 小时前
ajax局部更新
前端·ajax·okhttp
DoraBigHead3 小时前
React 架构重生记:从递归地狱到时间切片
前端·javascript·react.js
彩旗工作室4 小时前
WordPress 本地开发环境完全指南:从零开始理解 Local by Flywhee
前端·wordpress·网站