vue实现tree组件查询
Vue实现Tree组件查询功能
实现Tree组件查询功能需要结合树形数据结构和搜索逻辑
安装必要依赖(如element-ui的tree组件)
npm install element-ui
基础Tree组件实现
注册并使用el-tree组件

<template>
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
ref="tree"
></el-tree>
<el-input v-model="filterText" placeholder="输入关键字过滤"></el-input>
</template>
<script>
export default {
data() {
return {
filterText: '',
treeData: [{
label: '一级节点',
children: [{
label: '二级节点'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val)
}
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>
高级搜索功能实现
实现不区分大小写的搜索
filterNode(value, data) {
if (!value) return true
return data.label.toLowerCase().indexOf(value.toLowerCase()) !== -1
}
实现多字段搜索

filterNode(value, data) {
if (!value) return true
return (
data.label.toLowerCase().includes(value.toLowerCase()) ||
(data.description && data.description.toLowerCase().includes(value.toLowerCase()))
)
}
异步加载数据时的搜索
处理异步加载的树节点
async filterNode(value, data, node) {
if (!value) return true
// 如果节点未加载完成,先加载子节点
if (!node.loaded) {
await this.loadChildNodes(node)
}
// 检查当前节点和子节点是否匹配
return this.checkNodeAndChildren(value, data, node)
}
样式优化
添加搜索高亮效果
// 在filterNode方法中添加高亮逻辑
filterNode(value, data, node) {
if (!value) {
node.$el.innerHTML = data.label
return true
}
const match = data.label.match(new RegExp(value, 'i'))
if (match) {
const highlighted = data.label.replace(
new RegExp(value, 'gi'),
match => `<span style="color: #ff0;background: #f00;">${match}</span>`
)
node.$el.innerHTML = highlighted
return true
}
return false
}
性能优化
添加防抖处理频繁搜索
watch: {
filterText: {
handler: _.debounce(function(val) {
this.$refs.tree.filter(val)
}, 300),
immediate: false
}
}
完整组件示例
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字过滤" clearable></el-input>
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
node-key="id"
highlight-current
:expand-on-click-node="false"
></el-tree>
</div>
</template>
<script>
import _ from 'lodash'
export default {
data() {
return {
filterText: '',
treeData: [],
defaultProps: {
children: 'children',
label: 'name',
isLeaf: 'leaf'
}
}
},
created() {
this.fetchTreeData()
},
watch: {
filterText: _.debounce(function(val) {
this.$refs.tree.filter(val)
}, 300)
},
methods: {
async fetchTreeData() {
// 获取树形数据API调用
this.treeData = await getTreeData()
},
filterNode(value, data, node) {
if (!value) {
if (node.$el) node.$el.innerHTML = data.name
return true
}
const lowerValue = value.toLowerCase()
const match = data.name.toLowerCase().includes(lowerValue)
if (match && node.$el) {
const highlighted = data.name.replace(
new RegExp(value, 'gi'),
match => `<span class="highlight">${match}</span>`
)
node.$el.innerHTML = highlighted
}
return match || this.checkChildrenMatch(value, data)
},
checkChildrenMatch(value, data) {
if (!data.children) return false
return data.children.some(child => this.filterNode(value, child))
}
}
}
</script>
<style>
.highlight {
background-color: yellow;
color: #333;
font-weight: bold;
}
</style>






