前言:在项目中使用vue-antd的tree组件时,发现它的搜索功能没有达到我们项目的要求,所以将它的搜索功能优化了一下;
绘制的页面如下:
一、现在页面上绘制一个搜索框与tree组件
<div >
<a-input-search style="margin-bottom: 8px" placeholder="搜索" @search="searchOrg" v-model="searchPerson"></a-input-search>
<a-tree v-model="selectedKeys" default-expand-all :replace-fields="fieldNames" :selected-keys="selectedKeys" :tree-data="organizations" @select="onSelectTree"></a-tree>
</div>
二、js代码
实现思路:先将树结构转为数组,并找到筛选项匹配的值。通过这个值,找到对应所有的父元素,将所有父元素组成一个数组;最后再将这个数组转为树结构,重新渲染树组件;
const findParent = (id, list = [], pidName, result = []) => {
//找到子节点的所有相关父元素
for (let i = 0; i < list.length; i += 1) {
const item = list[i]
// 找到目标
if (item.id === id) {
// 加入到结果中
result.push({ id: item.id, name: item.name, pid: item[pidName] })
// 因为可能在第一层就找到了结果,直接返回当前结果
if (result.length === 1) return result
return true
}
// 如果存在下级节点,则继续遍历
if (item.children) {
// 预设本次是需要的节点并加入到最终结果result中
result.push({ id: item.id, name: item.name, pid: item[pidName] })
const find = findParent(id, item.children, pidName, result)
// 如果不是false则表示找到了,直接return,结束递归
if (find) {
return result
}
// 到这里,意味着本次并不是需要的节点,则在result中移除
result.pop()
}
}
// 如果都走到这儿了,也就是本轮遍历children没找到,将此次标记为false
return false
}
const translateArrToTree = (arr) => {
//将节点数组转为树结构
// 1.先是制作字典能够获得每一行的信息
const newArr = []
const map = []
arr.forEach(item => {
// 为了方便给每一项都添加上children
// 对象是直接.就可以添加属性的
item.children = []
const key = item.id
map[key] = item
});
// 2.遍历每一项,然后有父级的添加到父级的children中,没有父级的直接添加到新的数组中
arr.forEach(item => {
const parent = map[item.pid]
if (parent) {
parent.children.push(item)
} else {
newArr.push(item)
}
})
return newArr
}
generateList(data) {
//将树结构转为普通数组
for (let i = 0; i < data.length; i++) {
const node = data[i];
this.dataList.push({ key: node.id, title: node.name });
if (node.children) {
this.generateList(node.children);
}
}
},
searchOrg() {
this.dataList = []
this.organizations = this.organizationsData//树结构的数据
const value = this.searchPerson//筛选项
if (value) {
let treeArr = []
this.generateList(this.organizations)
this.dataList.forEach(item => {
if (item.title.indexOf(value) > -1) {
let parentList = findParent(item.key, this.organizations, 'pid')
treeArr = treeArr.concat(parentList) //合并所有满足条件数组
const obj = {} //数组去重
treeArr = treeArr.reduce((total, next) => {
obj[next.id] ? '' : obj[next.id] = true && total.push(next)
return total
}, [])
this.searchTree = translateArrToTree(treeArr)
}
return null;
})
this.organizations = this.searchTree
} else {
this.getDepartmentListTree()
}
},