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

1. 组件

src\components\menuTree\index.vue

<template>
    <template v-for="item in menuList">
        <!-- 分为两种方式渲染:有子菜单和没有子菜单-->
        <!--      没有子菜单-->
        <el-menu-item :index="item.path" v-if="item.children.length == 0" :key="item.path">
                <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>{{ 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>
})
</script>
<script lang="ts">
export default {
    name: "MenuTree"
}
</script>

注1: 组件自递时要导出
注2: 这里使用的图标是之前自定义的图标组件

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

2 . 使用示例

在父组件中:
数据根据自己的相应修改

<template>
    <div class="menu-container">
        <div class="up-title" v-if="!isCollapse">
            <!-- <div>
                <svg-icon name="" width="20px" height="20px" />
            </div> -->
            <div class="title-text">{{ !isCollapse ? "Vue3 boot3 快速开发平台" : "" }}</div>
        </div>
        <div class="down-menu">
            <el-menu :default-active="route.path" class="el-menu-vertical-demo" :collapse="isCollapse" :router="true" 
            :collapse-transition="false">
                <MenuTree :menuList="menuList"></MenuTree>
            </el-menu>
        </div>
    </div>
</template>

<script setup  lang="ts">
import { onMounted} from 'vue'
//渲染菜单的组件
import MenuTree from "@/components/menuTree/index.vue"
import { useMenuStore } from '@/stores/menu.js'
import { useRoute } from 'vue-router'

const menuStore = useMenuStore()
const route = useRoute()

// 获取pinia的缓存的菜单数据
const menuList = menuStore.menuList

const props = defineProps({
    isCollapse: Boolean
})


</script>

<style lang="scss">
.menu-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    .up-title {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        height: 5vh;
        // padding: 3px;
        /* 内边距 */
        border-bottom: 2px solid;
        border-right: 1px solid;
        /* 设置下边框宽度和样式 */
        border-color: #f5f5f5;

        .title-text {
            display: inline-block;
            vertical-align: middle;
            /* 文字与图片垂直居中对齐 */
            font-weight: bold;
            /* 加粗文字 */
            font-size: 13px;
            margin-left: 5px;
        }
    }

    .down-menu {
        flex-grow: 1;

    }
}

.el-menu-vertical-demo {
    height: 100%;
    overflow: auto;
}
</style>

在这里插入图片描述

3. 说明

  • 监听事件说明
    因为使用递归构造组件, 使用el-menu-item 添加事件会传播到el-sub-menu,会影响emit 向父组件发送数据,
    事件stop也会影响emit, 所以后续面包屑,tabs数据通过监听路由变化获取
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知所云,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值