vue实现树形控件
Vue 实现树形控件的方法
使用递归组件实现基础树形结构
递归组件是 Vue 中实现树形结构的核心方法。通过组件调用自身,可以动态渲染嵌套的树节点数据。
<template>
<div class="tree-node">
<div @click="toggle">{{ node.name }}</div>
<div v-show="isOpen" v-if="node.children">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
</div>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: {
node: Object
},
data() {
return {
isOpen: false
}
},
methods: {
toggle() {
this.isOpen = !this.isOpen
}
}
}
</script>
使用第三方组件库快速实现
Element UI、Ant Design Vue 等流行 UI 库都提供了成熟的树形控件实现。
安装 Element UI:
npm install element-ui
使用示例:
<template>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
/>
</template>
<script>
export default {
data() {
return {
treeData: [{
label: '一级节点',
children: [{
label: '二级节点'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick(data) {
console.log(data)
}
}
}
</script>
实现可拖拽的树形结构
通过引入拖拽库实现节点拖拽排序功能。

使用 sortablejs 实现:
npm install sortablejs
实现代码:
<template>
<div ref="tree">
<tree-node
v-for="node in treeData"
:key="node.id"
:node="node"
/>
</div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
mounted() {
this.setSortable()
},
methods: {
setSortable() {
new Sortable(this.$refs.tree, {
handle: '.drag-handle',
animation: 150,
onEnd: this.onSortEnd
})
},
onSortEnd(evt) {
// 处理排序后的数据更新
}
}
}
</script>
实现树节点的增删改查功能
为树形控件添加完整的 CRUD 操作功能。

<template>
<div>
<el-tree
ref="tree"
:data="treeData"
node-key="id"
default-expand-all
/>
<el-button @click="addNode">添加节点</el-button>
<el-button @click="removeNode">删除节点</el-button>
</div>
</template>
<script>
export default {
methods: {
addNode() {
const newNode = { id: Date.now(), label: '新节点' }
this.$refs.tree.append(newNode, this.$refs.tree.getCurrentNode())
},
removeNode() {
this.$refs.tree.remove(this.$refs.tree.getCurrentNode())
}
}
}
</script>
实现树节点的懒加载
对于大数据量的树形结构,实现按需加载子节点。
<template>
<el-tree
:props="props"
:load="loadNode"
lazy
/>
</template>
<script>
export default {
data() {
return {
props: {
label: 'name',
children: 'zones',
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>
实现树形表格
结合表格展示树形数据,实现更复杂的数据展示需求。
<template>
<el-table
:data="tableData"
row-key="id"
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="date" label="日期"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
id: 1,
date: '2023-01-01',
name: '一级',
children: [{
id: 2,
date: '2023-01-02',
name: '二级'
}]
}]
}
}
}
</script>
实现树形选择器
将树形结构封装为选择器组件,方便表单使用。
<template>
<el-popover
ref="popover"
placement="bottom-start"
trigger="click"
>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
/>
<el-input
slot="reference"
v-model="selectedLabel"
readonly
placeholder="请选择"
/>
</el-popover>
</template>
<script>
export default {
data() {
return {
selectedLabel: '',
treeData: [/* 树数据 */],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
methods: {
handleNodeClick(data) {
this.selectedLabel = data.label
this.$refs.popover.doClose()
}
}
}
</script>






