在写项目的时候碰到的,写一个树组件(原以为特简单,只到数据量特别大),我用了default-expand-all(展开全部节点)直接崩了 (╯‵□′)╯︵┻━┻
然后开始是用懒加载,写完之后只有全部展开之后才能内部搜索,显然不符合用户体验(几千上万个数据中找几个没有直接搜,简直反人类)
最后就是写两个树,一个懒加载,一个后台搜索拿到渲染一个新树,两个来回切换
懒加载请求的树以下简称懒加载树,搜索获取数据渲染新树以下简称搜索树
<div>
<el-input v-model="searchMsg" size="medium" suffix-icon="el-icon-search"></el-input>
</div>
<div class="tree">
<!-- <keep-alive> -->
<el-tree
class="tree1"
v-show="treeShow"
key="1"
:data="treeData"
show-checkbox
node-key="id"
:default-expanded-keys="[chooseTree]"
:default-checked-keys="[...selectedSN]"
@check-change="getChecked"
default-expand-all
ref="tree">
</el-tree>
<!-- :filter-node-method="filterNode" -->
<el-tree
class="tree2"
v-show="!treeShow"
key="2"
node-key="id"
:default-expanded-keys="[chooseTree]"
@check-change="getChecked2"
expand-on-click-node
:default-checked-keys="[...selectedSN2]"
:props="defaultProps"
:load="loadNode"
lazy
show-checkbox
ref="tree2">
</el-tree>
<!-- </keep-alive> -->
</div>
v-if和v-show都行,但是v-if需要在树组件外层加一个keep-alive缓存组件,不然会反复销毁报错
watch:{
if (this.searchMsg&&this.treeShow==false) { //判断是否搜索&&显示的是不是懒加载树
this.treeShow = true
this.selectedSN = this.selectedSN2 //给懒搜索树赋值
this.searchStation()
}else if(this.searchMsg&&this.treeShow){//新加的这个判断为了避免输入多个文字,删除调用进不到上面的问题,并且可能选择了需要push合并一下
//判断是否搜索&&显示的是不是搜索树
this.selectedSN2.push(...this.selectedSN)
this.selectedSN = this.selectedSN2
this.searchStation()
}else{
this.selectedSN2.push(...this.selectedSN)
this.$refs.tree2.setCheckedKeys(Array.from(new Set(this.selectedSN2)))
this.treeShow = false
}
监听searchMsg,有值说明是搜索,为''则显示懒加载树
getChecked(data,state){ //获取id
if (state == false) {//判断是state,true为勾选,false为取消勾选
let index;
this.selectedSN2.map((item,index1)=>{
//获取取消的下边,用于删除this.selectedSN2中的勾选项,这个我们上面的
//this.selectedSN2.push(...this.selectedSN)就不会拿到在搜索树取消,懒加载树上存在此勾选的值
if (item == data.id) {
index= index1
}
})
if(index>=0){
this.selectedSN2.splice(index,1)
//删除在搜索树上取消勾选的值(在懒加载勾选abc,搜索abc会为勾选状态
//( this.selectedSN = this.selectedSN2 //懒加载树上的勾选项赋值给搜索树)这个赋值的作用),
//在搜索树上取消,就需要我们把兰家紫树上也删除掉
}
}
this.chooseTree=this.$refs.tree.getCheckedKeys()
let newArr=[]
this.chooseTree.forEach((ele,index,arr)=>{//判断父节点并返回子节点
if(arr[index]>9999){
newArr.push(arr[index])
}
})
this.selectedSN = newArr
},
getChecked2(data,data1,data2){ //获取id
this.chooseTree2=this.$refs.tree2.getCheckedKeys()
let newArr=[]
this.chooseTree2.forEach((ele,index,arr)=>{//判断父节点并返回子节点,我的是因为有国家省市id不会大于9999,我需要过滤一下
if(arr[index]>9999){
newArr.push(arr[index])
}
})
this.selectedSN2 = newArr
},
searchStation(){ //搜索
let data={
snType:0,
searchInfo:this.searchMsg,
searchType:this.value,
}
this.$api.stationFindStation(data).then(res=>{
this.treeData=res.data.data //搜索树的数据
this.$refs.tree.setCheckedKeys(this.selectedSN) //给搜索树设置勾选项
})
},
loadNode(node, resolve) { //懒加载,点击展开触发
let data;
if(node.level == 0){
data = {
type:node.level,
snType:0
}
}else {
data = {
type:node.level,
id:node.data.id,
snType:0
}
}
this.$api.stationFindStation(data).then(res=>{
this.data = res.data.data
setTimeout(()=>{
resolve(this.data); //懒加载的数据插进去
this.$refs.tree2.setCheckedKeys(this.selectedSN2)//设置勾选
},300)
})
},
search(){
this.selectedSN2.push(...this.selectedSN)
this.$refs.tree2.setCheckedKeys(Array.from(new Set(this.selectedSN2)))
//我的主要数据在懒加载树上,防止他在搜索树上直接去查询,合并一下勾选项
let inverterIds=[],stationIds=[]
this.selectedSN2.map((item,index)=>{
if((this.$refs.tree.getNode(item)&&this.$refs.tree.getNode(item).data.leaf)||(this.$refs.tree2.getNode(item)&&this.$refs.tree2.getNode(item).data.leaf)){
//判断在哪个树上有,leaf这个是defaultProps中的代表是否为父节点,显示可以展开的箭头,最后一级为leaf:true,别的都没有做判断
inverterIds.push(item)
inverterIds = Array.from(new Set(inverterIds)) //去重
this.inverterIds = inverterIds.join(',')
}else{
stationIds.push(item)
stationIds = Array.from(new Set(stationIds)) //去重
this.stationIds = stationIds.join(',')
}
})
console.log(this.inverterIds+'---------'+this.stationIds)
//区分出来是最后一级的id,还是倒数第二级的id,分开传给后台实现查询
},
这个我在网上没找到,自己写了一个,水平不咋地,见谅见谅