功能:
1、树懒加载
2、查询
3、关键字高亮显示
4、初始化加载展开4层
构造原因:ant-tree异步加载数据查询之后,节点不支持再次请求数据,直接渲染全部节点后,数据量特别大(生成dom进行操作),会造成浏览器卡顿
思路:
1、switcherIcon重写自定义树节点的展开/折叠图标
2、通过loaded状态判断是否完成了懒加载,当懒加载进行时,用loading状态更改图标
3、每次懒加载之后,给数据新建一个空的子节点,进行伪造懒加载(只有节点下有孩子节点时,才会有图标)
view视图
<a-input-search @search="onSearch" v-model.trim="searchStr"></a-input-search>
<a-tree
@select="onSelect"
:selectedKeys="selectedKeys"
:treeData="treeData"
:expandedKeys="expandedKeys"
@expand="changeExpand"
:replaceFields="{key:'id',title:'title',children:'children'}"
>
<template slot="switcherIcon" slot-scope="{loading}">
<a-icon type="caret-down" v-if="loading"></a-icon>
<a-icon type="loading" v-else></a-icon>
</template>
<template slot="title" slot-scope="{title}">
<span v-html="
title
? title.replace(
new RegExp(replaceKeywords,g),
'<span style=color:#f50>'+title+'</span>'
)
: null"
></span>
</template>
</a-tree>
加载树
loadingData为最后展开的一层节点,方便首次加载默认展开层级
async loadTree(treeId,treeNode,isSearch){
let params={treeId}
let [err,res] = await loadTree(params);
if(!err){
if(res.result.code == 200){
//存在树节点
if(treeId){
treeNode.dataRef.children = this.getUpdateTree(res.result.data);
this.treeData = [...this.treeData];
this.loadingData = res.result.data
}else{
if(isSearch){
this.treeData = res.result.data;
this.expandedKeys = [];
this.getAllKey(this.treeData)
}else{
this.treeData = this.getUpdateTree(res.result.data);
if(!this.treeData.length){return;}
//首次加载默认加载到第四层
this.expandedKeys = []
this.initTree(this.treeData,1,4)
}
}
}
}
}
initTree:初始化循环树,默认展示到第几层
async initTree(treeData,index,maxLevel){
if(index > maxLevel || !treeData.length){return};
treeData.map(item=>{
if(item.childrenIds.length){
let initLoaded = item.loaded;
item.loaded = true;
item.loading = true;
let data = {dataRef:item}
if(initLoaded){
index++;
treeData = item.children
this.initTree(treeData,index,maxLevel);
item.loading = false;
this.expandedKeys.push(item.id);
return;
}
setTimeOut(
async ()=>{
let returnData = await this.onLoadData(data);
if(returnData.length){
index++;
treeData = this.loadingData;
this.initTree(treeData,index,maxLevel);
item.loading = false;
this.expandedKeys.push(item.id);
}
},
initLoaded ? 0 :100
)
}
})
}
onLoadData:懒加载
onLoadData(treeNode){
return new Promise(resolve=>{
setTimeout(()=>{
treeNode.dataRef.loading = false;
resolve(this.loadTree(treeNode.dataRef.id,treeNode))
},10)
})
}
getUpdateTree:添加一个空数组,伪造懒加载
getUpdateTree(data){
data.map(item=>{
if(存在子节点){
item.children = [{}]
}
})
}
getAllKey:获取树节点所有的key
getAllKey(data){
data.map(item=>{
this.expandedKeys.push(item.id);
if(item.children){
this.getAllKey(item.children)
}
})
}
onSearch:搜索
onSearch(){
this.expandedKey = []
this.searchKeywords = this.searchStr;
//替换特殊字符
this.replaceKeywords = this.searchStr.split("\\").join("\\\\");
this.replaceKeywords = this.replaceKeywords.split("[").join("\\[");
this.replaceKeywords = this.replaceKeywords.split("]").join("\\]");
this.replaceKeywords = this.replaceKeywords.split("$").join("\\$");
this.replaceKeywords = this.replaceKeywords.split("^").join("\\^");
this.replaceKeywords = this.replaceKeywords.split("*").join("\\*");
this.replaceKeywords = this.replaceKeywords.split("(").join("\\(");
this.replaceKeywords = this.replaceKeywords.split(")").join("\\)");
this.replaceKeywords = this.replaceKeywords.split("+").join("\\+");
this.replaceKeywords = this.replaceKeywords.split("|").join("\\|");
this.replaceKeywords = this.replaceKeywords.split("?").join("\\?");
this.loadTree("","",true)
}
changeExpand:点击判断是否异步加载
changeExpand(event,node){
if(node.node.dataRef.loaded){
this.expandedKeys = event;
return;
}
node.node.dataRef.loading = true;//添加懒加载效果
node.node.dataRef.loaded = true;//当点击时,表示已经加载
this.onLoadData(node.node);
this.expandedKeys = event
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。