vue实现树形选择框
Vue 实现树形选择框的方法
使用第三方组件库(推荐)
对于快速实现树形选择框,推荐使用成熟的第三方组件库,例如 Element UI 或 Ant Design Vue,它们提供了开箱即用的树形选择组件。
Element UI 示例:
<template>
<el-tree-select
v-model="selectedValue"
:data="treeData"
:props="defaultProps"
check-strictly
placeholder="请选择"
/>
</template>
<script>
export default {
data() {
return {
selectedValue: '',
treeData: [
{
label: '一级 1',
children: [
{ label: '二级 1-1' },
{ label: '二级 1-2' }
]
},
{
label: '一级 2',
children: [
{ label: '二级 2-1' },
{ label: '二级 2-2' }
]
}
],
defaultProps: {
children: 'children',
label: 'label'
}
};
}
};
</script>
Ant Design Vue 示例:

<template>
<a-tree-select
v-model:value="selectedValue"
:tree-data="treeData"
placeholder="请选择"
style="width: 100%"
/>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const selectedValue = ref();
const treeData = [
{
title: 'Node1',
value: '0-0',
children: [
{ title: 'Child Node1', value: '0-0-1' }
]
},
{
title: 'Node2',
value: '0-1'
}
];
return { selectedValue, treeData };
}
};
</script>
手动实现树形选择框
如果需要完全自定义树形选择框,可以通过递归组件实现。
递归组件实现:

<template>
<div class="tree-select">
<div
v-for="node in treeData"
:key="node.id"
class="tree-node"
>
<div
class="node-label"
@click="toggleNode(node)"
>
{{ node.label }}
<span v-if="node.children">
{{ node.expanded ? '−' : '+' }}
</span>
</div>
<div
v-if="node.expanded && node.children"
class="children"
>
<tree-node
:tree-data="node.children"
@select="handleSelect"
/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: {
treeData: Array
},
methods: {
toggleNode(node) {
if (node.children) {
node.expanded = !node.expanded;
} else {
this.$emit('select', node);
}
},
handleSelect(node) {
this.$emit('select', node);
}
}
};
</script>
<style>
.tree-select {
border: 1px solid #ddd;
padding: 8px;
max-height: 300px;
overflow-y: auto;
}
.tree-node {
margin-left: 16px;
}
.node-label {
cursor: pointer;
padding: 4px 0;
}
.children {
margin-left: 16px;
}
</style>
实现搜索功能
对于大型树形数据,可以添加搜索功能过滤节点。
搜索过滤实现:
<template>
<div>
<input
v-model="searchText"
placeholder="搜索节点"
/>
<tree-node
:tree-data="filteredTree"
@select="handleSelect"
/>
</div>
</template>
<script>
export default {
data() {
return {
searchText: '',
treeData: [
// 树形数据
]
};
},
computed: {
filteredTree() {
if (!this.searchText) return this.treeData;
const filter = (nodes) => {
return nodes.filter(node => {
const matches = node.label.includes(this.searchText);
if (node.children) {
const filteredChildren = filter(node.children);
if (filteredChildren.length > 0) {
return { ...node, children: filteredChildren };
}
}
return matches;
});
};
return filter(this.treeData);
}
}
};
</script>
注意事项
- 如果树形数据层级较深,建议使用虚拟滚动优化性能。
- 对于多选功能,需要维护选中的节点状态。
- 大型数据建议使用懒加载方式动态加载子节点。
以上方法可以根据实际需求选择使用,第三方组件库适合快速开发,手动实现适合高度定制化场景。






