vue实现多级目录
实现多级目录的核心思路
使用递归组件处理嵌套数据结构,通过v-for动态渲染每一级目录项,结合v-if或计算属性控制子目录的展开/折叠状态。关键点在于组件自身调用自身。
基础数据结构示例
data() {
return {
menuItems: [
{
name: '一级目录',
children: [
{
name: '二级目录',
children: [
{ name: '三级目录', children: [] }
]
}
]
}
]
}
}
递归组件实现
创建TreeMenu.vue组件:
<template>
<ul>
<li v-for="(item, index) in list" :key="index">
<div @click="toggleChildren(item)">
{{ item.name }}
<span v-if="item.children && item.children.length">
{{ item.isOpen ? '-' : '+' }}
</span>
</div>
<tree-menu
v-if="item.children && item.children.length && item.isOpen"
:list="item.children"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: {
list: Array
},
methods: {
toggleChildren(item) {
this.$set(item, 'isOpen', !item.isOpen)
}
}
}
</script>
在父组件中使用
<template>
<div>
<tree-menu :list="menuItems" />
</div>
</template>
<script>
import TreeMenu from './TreeMenu.vue'
export default {
components: { TreeMenu },
data() {
return {
menuItems: [...]
}
}
}
</script>
样式优化建议
ul {
list-style-type: none;
padding-left: 20px;
}
li {
cursor: pointer;
margin: 5px 0;
}
动态加载数据方案
对于大型目录结构,可采用懒加载方式:

async loadChildren(item) {
if (!item.children || item.children.length === 0) {
const res = await api.getChildren(item.id)
this.$set(item, 'children', res.data)
}
this.$set(item, 'isOpen', !item.isOpen)
}
性能优化提示
- 为每项添加唯一
key - 复杂目录使用虚拟滚动
- 深层嵌套时考虑扁平化数据结构
- 使用
Object.freeze()处理静态数据
完整功能扩展方向
- 添加复选框联动功能
- 实现拖拽排序
- 增加搜索过滤功能
- 支持右键上下文菜单
- 添加动画过渡效果






