vue实现目录树
vue实现目录树的方法
递归组件实现
使用递归组件可以轻松实现无限层级的目录树结构。需要定义一个组件,该组件能够调用自身来渲染子节点。
<template>
<ul>
<li v-for="item in treeData" :key="item.id">
{{ item.name }}
<tree-node v-if="item.children" :treeData="item.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeNode',
props: {
treeData: Array
}
}
</script>
使用第三方库
对于更复杂的需求,可以使用成熟的第三方树形组件库,如vue-tree-halower或element-ui的el-tree组件。
安装element-ui后:
<template>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick">
</el-tree>
</template>
<script>
export default {
data() {
return {
treeData: [{
label: '一级节点',
children: [{
label: '二级节点'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick(data) {
console.log(data);
}
}
}
</script>
动态加载数据
对于大型目录树,可以采用动态加载方式,当展开节点时才加载其子节点数据。
<template>
<el-tree
:props="props"
:load="loadNode"
lazy>
</el-tree>
</template>
<script>
export default {
data() {
return {
props: {
label: 'name',
children: 'children',
isLeaf: 'leaf'
}
}
},
methods: {
loadNode(node, resolve) {
if (node.level === 0) {
// 加载根节点
return resolve([{ name: '根节点' }]);
}
if (node.level > 3) {
// 设置叶子节点
return resolve([]);
}
// 模拟异步加载
setTimeout(() => {
resolve([{
name: '子节点' + node.level
}]);
}, 500);
}
}
}
</script>
自定义节点内容
可以通过scoped slot自定义每个节点的渲染内容,实现更灵活的UI设计。
<template>
<el-tree
:data="treeData"
:props="defaultProps">
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<el-button
size="mini"
@click="append(data)">
添加
</el-button>
</span>
</span>
</el-tree>
</template>
状态管理
对于需要跨组件共享状态的目录树,可以使用Vuex来管理树形数据的状态。
// store.js
export default new Vuex.Store({
state: {
treeData: []
},
mutations: {
updateTreeData(state, payload) {
state.treeData = payload
}
},
actions: {
fetchTreeData({commit}) {
// 获取数据后commit
commit('updateTreeData', data)
}
}
})
性能优化
对于大型目录树,可以采用虚拟滚动技术优化性能,只渲染可视区域内的节点。

<template>
<virtual-tree
:data="treeData"
:item-size="30"
:height="500">
<template v-slot="{ item }">
<div>{{ item.name }}</div>
</template>
</virtual-tree>
</template>






