摘要
element plus的菜单只能到达二级,有的时候需求可能达到多级菜单,因此编写此文章,学习如何开发多级菜单组件
菜单组件
<template>
<div>
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="2"
text-color="#fff"
>
//将所有菜单一起遍历传递给子组件,让子组件判断菜单是否有子菜单
<MenuComponent
v-for="menuItem in MenuList"
:key="menuItem.name"
:menuItem="menuItem"
></MenuComponent>
</el-menu>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
import MenuComponent from "./MenuComponent.vue";
export default defineComponent({
name: "Menu",
setup() {
const MenuList = reactive([
{
path: "./",
name: "Home",
title: "主页",
},
{
path: "./vue",
name: "Vue",
title: "vue学习",
childrens: [
{
path: "/vueIdRouter",
name: "VueIdRouter",
title: "vue-动态传值",
childrens: [
{
path: "/vueIdRouter-子菜单",
name: "VueIdRouter-子菜单",
title: "vue-动态传值-子菜单",
childrens: [
{
path: "/vueIdRouter-子菜单22",
name: "VueIdRouter-子菜单22",
title: "vue-动态传值-子菜单22",
},
],
},
],
},
{
path: "/vueIdRouter-没有子菜单",
name: "VueIdRouter-没有子菜单",
title: "vue-动态传值-没有子菜单",
},
{
path: "/vueIdRouter3",
name: "VueIdRouter3",
title: "vue-动态传值3",
childrens: [
{
path: "/vueIdRouter-子菜单3",
name: "VueIdRouter-子菜单3",
title: "vue-动态传值-子菜单3",
childrens: [
{
path: "/vueIdRouter-子菜单33",
name: "VueIdRouter-子菜单33",
title: "vue-动态传值-子菜单33",
},
],
},
],
},
],
},
]);
return {
MenuList,
MenuComponent,
};
},
});
</script>
菜单遍历组件
<template>
//有子菜单
<el-sub-menu
v-if="menuItem.childrens && menuItem.childrens.length"
:index="menuItem.name"
>
<template #title>
{{ menuItem.title }}
</template>
//有子菜单 调用当前组件
<MenuComponent
v-for="child in menuItem.childrens"
:key="child.name"
:menuItem="child"
></MenuComponent>
</el-sub-menu>
//没有子菜单
<el-menu-item v-else :index="menuItem.name">
{{ menuItem.title }}
</el-menu-item>
</template>
<script lang="ts">
import { defineComponent } from "vue";
//定义菜单对象的数据类型
interface MenuItem {
path: string;
name: string;
title: string;
//子菜单可能存在也可能不存在,子菜单里还有相同的数据类型
//注意:
//这里没有问号会导致Menu.vue报错,因为没有问号就规定传递的菜单对象必有子菜单,如果没有MenuItem,当前组件MenuComponent.vue就会报错,因为那就规定子菜单必是空对象,但是子菜单除了可能为空,也可能有数据
childrens?: MenuItem[];
}
export default defineComponent({
name: "MenuComponent",
//通过props接受数据
props: {
menuItem: {
//断言绑定类型
type: Object as () => MenuItem,
//require:true 是一种约束,确保组件在使用时能够正确地接收必要的数据,有助于在开发阶段捕获潜在的错误。
required: true,
},
},
});
</script>