返回
解析 PC 项目实战(一):el-menu 构建多层级树状菜单,简单易懂!
前端
2024-01-30 00:09:52
前言
树状菜单是一种常见的 UI 组件,它可以将数据结构化地组织成一棵树状结构,方便用户浏览和选择。在本文中,我们将探讨如何使用 Vue.js 的 el-menu 组件构建一个多层级的树状菜单。
需求说明
我们希望实现一个动态渲染的树状菜单,其中菜单项可以根据后端返回的嵌套数据进行更新。菜单分为两种类型:
- 菜单: 不可点击,只能下拉打开子菜单。
- 功能: 可以点击,执行特定操作。
菜单类型由 menuType
字段区分。
需求实现
封装子菜单组
首先,我们需要封装一个子菜单组组件,它将负责渲染菜单项及其子菜单。
<template>
<el-menu-item :index="index" :class="{'is-active': isActive}">
<template v-if="menu.children">
<span slot="title">{{ menu.label }}</span>
<el-menu v-bind="$attrs" :default-active="activeName">
<sub-menu v-for="subMenu in menu.children" :key="subMenu.index" :menu="subMenu" :index="subMenu.index" />
</el-menu>
</template>
<template v-else>
<el-menu-item :index="index" :class="{'is-active': isActive}">{{ menu.label }}</el-menu-item>
</template>
</el-menu-item>
</template>
<script>
export default {
props: ['menu', 'index', 'activeName'],
data() {
return {
isActive: false
}
},
methods: {
handleOpen() {
this.isActive = true
},
handleClose() {
this.isActive = false
}
}
}
</script>
在子菜单组中,我们使用递归的方式来渲染子菜单。当菜单项具有子菜单时,我们渲染一个 el-menu 组件并将其传递给子菜单组。当菜单项没有子菜单时,我们直接渲染一个 el-menu-item。
菜单渲染
接下来,我们需要在父组件中渲染菜单。
<template>
<el-menu v-model="activeName" @open="handleOpen" @close="handleClose">
<sub-menu v-for="menu in menuData" :key="menu.index" :menu="menu" :index="menu.index" />
</el-menu>
</template>
<script>
import SubMenu from './SubMenu.vue'
export default {
components: { SubMenu },
data() {
return {
menuData: [
{
index: 0,
label: '菜单 1',
children: [
{ index: 1, label: '子菜单 1' },
{ index: 2, label: '子菜单 2' }
]
},
{
index: 1,
label: '功能 2',
menuType: 'function'
}
],
activeName: ''
}
},
methods: {
handleOpen(name) {
this.activeName = name
},
handleClose() {
this.activeName = ''
}
}
}
</script>
在父组件中,我们使用 v-model 来控制菜单的选中状态,并监听 open 和 close 事件。当菜单项被打开或关闭时,我们相应地更新 activeName。
总结
通过上述步骤,我们成功构建了一个多层级的树状菜单,它可以根据后端返回的嵌套数据进行动态渲染。菜单类型由 menuType 字段区分,并支持可点击的功能菜单项。