Vue.js 递归组件实战:从零构建树形菜单与树形表格
本文详解Vue.js中递归组件的核心机制,重点讲解通过name属性实现组件自我调用的方法。通过模拟数据与完整代码示例,演示如何构建支持无限层级嵌套的树形菜单,并展示如何在此基础上扩展实现树形表格功能,帮助开发者掌握复杂UI组件的开发技巧。
递归组件基础概念
递归组件
在Vue中,组件可以在其模板内部递归调用自身,但前提是必须定义name选项。这是实现递归组件的关键约束,因此定义组件时务必包含name属性。基于这一原则,我们开始具体实现。
树形菜单实现步骤
最终实现的界面效果如下所示:
模拟的数据结构格式如下:
var data = [{
"id": "1",
"data": {
"menuName": "项目管理",
"menuCode": "",
},
"childTreeNode": [{
"data": {
"menuName": "项目",
"menuCode": "BusProject",
},
"childTreeNode": []
}, {
"data": {
"menuName": "我的任务",
"menuCode": "BusProject",
},
"childTreeNode": []
}, {
"data": {
"menuName": "人员周报",
"menuCode": "BusProject",
},
"childTreeNode": []
}]
}, {
"id": "2",
"data": {
"menuName": "数据统计",
"menuCode": "BusClock",
},
"childTreeNode": []
}, {
"id": "3",
"data": {
"menuName": "人事管理",
"menuCode": "",
},
"childTreeNode": []
}, {
"id": "4",
"data": {
"menuName": "基础管理",
"menuCode": "",
},
"childTreeNode": []
}]
HTML结构的实现思路是在ul标签内嵌套li标签,形成无限层级的ul套li结构,标题部分则使用div元素进行包裹。
<li>
<div @click='toggle'>
<i v-if='isFolder' class="fa " :class="[open?'fa-folder-open':'fa-folder']"></i>
<!--isFolder判断是否存在子级改变图标-->
<i v-if='!isFolder' class="fa fa-file-text"></i> {{model.data.menuName}}
</div>
<ul v-show="open" v-if='isFolder'>
<items v-for='cel in model.childTreeNode' :model='cel'></items>
</ul>
</li>
官方文档明确指出,实现递归组件必须使用name属性。
export default {
name: 'items',
props: ['model'],
components: {},
}
遵循Vue不直接操作DOM树的理念,我们定义了两个数据变量:open用于控制子菜单的显示与隐藏,isFolder用于标识是否存在子菜单以切换图标样式。
data() {
return {
open: false,
isFolder: true
}
}
利用Vue的计算属性动态计算isFolder的值,从而修改图标显示。该属性通过判断是否存在子级以及子级的长度来确定状态。
computed: {
isFolder() {
return this.model.childTreeNode && this.model.childTreeNode.length
}
}
接下来处理显示与隐藏的交互事件。
methods: {
toggle: function() {
if(this.isFolder) {
this.open = !this.open
}
}
}
至此,一个基础的树形菜单功能已经实现,最终样式效果留给大家自行调整,此处提供完整代码供参考。
<template>
<li>
<div @click='toggle'>
<i v-if='isFolder' class="fa " :class="[open?'fa-folder-open':'fa-folder']"></i>
<!--isFolder判断是否存在子级改变图标-->
<i v-if='!isFolder' class="fa fa-file-text"></i> {{model.data.menuName}}
</div>
<ul v-show="open" v-if='isFolder'>
<items v-for='cel in model.childTreeNode' :model='cel'></items>
</ul>
</li>
</template>
<script type="text/javascript">
export default {
name: 'items',
props: ['model'],
components: {},
data() {
return {
open: false,
isFolder: true
}
},
computed: {
isFolder: function() {
return this.model.childTreeNode && this.model.childTreeNode.length
}
},
methods: {
toggle: function() {
if(this.isFolder) {
this.open = !this.open
}
},
}
}
</script>
从树形菜单到树形表格
公司早期管理系统基于easyui构建,接手后使用Vue完整复刻了部分easyui的功能。下图展示了在树形菜单基础上进一步模仿实现的树形表格效果。
总结
以上就是本文的全部内容,希望这些内容能对各位的学习或工作有所帮助。如有任何疑问,欢迎留言交流。
怎么在Vue3项目中集成轻量级JS文本编辑器
2026-11-03 12:21:35
Vue.js官网怎么切换Vue 2与Vue 3版本文档?避免看错版本指南
2026-11-03 08:08:08
ElementUI el-switch 开关组件使用详解与高级应用
2026-10-31 15:21:18
Element UI 表格行按钮点击加载与状态管理实现
2026-10-31 14:12:32
fullCalendar日历插件高级用法与源码修改实战
2026-10-31 10:19:16
