树状搜索参照element树过滤方法进行解析
假设后端传递树状结构为data
data: [
{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 11',
}, {
id: 10,
label: '三级 12'
},{
id: 11,
label: '三级 13'
}]
},{
id: 12,
label: '二级 1-2',
children: [{
id: 13,
label: '三级 121'
}, {
id: 14,
label: '三级 122'
},{
id: 15,
label: '三级 123'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}
]
过滤条件:显示节点中含有搜索值searchValue的结点
function filterNodeMethod(nodeData){
return nodeData.label.indexOf(this.searchValue) !== -1;//结点名称中包含搜索值value返回true,否则返回false
}
搜索方法search:改变data数据
search(){
let t = this.filterNodeMethod
let array = []
this.data.forEach((item)=>{
n(item)
if(item.visible){
array.push(item)
}
})
function n(r){
var s = r.children ? r.children : []
if (s.forEach(function(i) {
i.visible = t(i)
n(i)//递归
}), !r.visible && s.length) {//做完前面的所有递归,当该节点的visible还是false,且children数组长度不为空,就去遍历children看里面的结点的visible有没有true的如果有那么说明这个结点也是true,把他变成true。
let visible = false
let pd = []
s.forEach((e,index)=>{
if(e.visible){
visible = true
pd.push(e)
}
})
r.children = pd
r.visible = visible
}
}
this.data = array
console.log("this.data",this.data)
},
假设searchValue为3整颗树节点递归的顺序为:
一级1:false
二级1-1:false
三级11:false,三级12:false,三级13:true,由于这三个没有子节点,判断子节点长度为0所以不用做内部结点遍历判断状态,只要做完自身判断
由于二级1-1整个结点包括内部子节点全部做完判断,所以要遍历内部子结点(三级11:false,三级12:false,三级13:true)判断自身结点状态,二级1-1:true,并去除visible为false的子节点
二级1-2:false
三级121:false,三级122:false,三级123:true,,由于这三个没有子节点,判断子节点长度为0所以不用做内部结点遍历判断状态,只要做完自身判断
由于二级1-2整个结点包括内部子节点全部做完判断,所以要遍历内部子结点(三级121:false,三级122:false,三级123:true)判断自身结点状态,二级1-2:true,并去除visible为false的子节点
由于一级1整个结点包括内部子节点全部做完判断,所以要遍历内部子结点(二级1-1:true,二级1-2:true)判断自身结点状态,二级1:true
以下结点同理
如果是纯前端做搜索功能一旦改变data数据,再次获取全部数据要不重新请求,要不就要在初始把全部数据存储起来
看了element的做法是利用之前的visible作为判断依据来隐藏和显示结点,为false的隐藏,这也是一种方法,这样的话就不用对不符合要求的结点进行去除了
search(){
let t = this.filterNodeMethod
this.data.forEach((r)=>{
n(r)
})
function n(r){
var s = r.children ? r.children : []
debugger
if (s.forEach(function(i) {
i.visible = t(i),
console.log('visible',i.visible)
n(i)
}), !r.visible && s.length) {
let visible = false
s.forEach(function(e) {
if(e.visible){
visible = true
}
})
r.visible = visible
}
}
console.log("this.data",this.data)
},