一、需求描述
项目中有个需求:从脚本结果查询页面跳转到在线sql页面,脚本目录树形懒加载下默认显示到第三级节点。
效果如下图所示:
二、思路及功能实现
对于树形懒加载,我使用Element-UI tree组件的load方法结合lazy属性来实现。主要还是和后台商量确定好数据结构。了解到Element-UI tree懒加载下,后台需要返给前端数组结构(即返回的每一级节点数据结构是数组),同时后台也要返回一个是否是子节点标识,要不然前端无法知道需不需要去加载下一节点。tree组件有个默认展开的节点属性是default-expanded-keys,把默认展示的节点key放进这个数组里。
思路:基于项目需求,从结果查询页面跳转到这个页面需要有个标识,要不然不知道从哪个页面调过来,页面上我传来一个布尔标识isExpandShow。对于默认展开的节点,需要递归调用接口,把递归遍历到node的level为2的节点数据放入默认展开的节点数组里。
主要代码如下:
<el-tab-pane label="Scripts" name="Scripts">
<div v-if="activeName === 'Scripts' ">
<el-tree
ref="scriptTree"
:load="loadScriptNode"
lazy
node-key="name"
:props="defaultProps"
highlight-current
:default-expanded-keys="defaultExpandedKey"
@node-click="treeNodeScriptClick">
<span class="slot-t-node" slot-scope="{ node,data }">
<el-icon icon-class="tree" />
<span>{{ node.label }}</span>
</span>
</el-tree>
</div>
</el-tab-pane>
data(){
return{
//脚本节点属性
defaultProps: {
label: "name",
children: "dataList",
isLeaf: 'leaf',
expanded:'expanded'
},
defaultExpandedKey:[],//默认展示节点数组
}
}
methods:{
//脚本文件-初始化获取根节点数据
queryScriptTables(resolve){
let params={
extId:parseInt(this.$route.query.leafExtId) ||
parseInt(this.$route.query.resultExtId) || '',
level:0,
}
getScriptList(params).then((res)=>{
if(res.data.code === 200 ){
let data = res.data.data;
// console.log(data)
// 判断根目录是原始文件目录还是转换文件目录
if(data){
// 如果是从结果页面跳转过来
if(this.$route.query.isExpandShow){
let tempArray=[];
data.forEach((k)=>{
// 把每一级节点返回的结果放入defaultExpandedKey中
tempArray.forEach((item)=>{
// 去重
if(item.name === k.name){
return;
}
})
tempArray.push(k);
})
this.defaultExpandedKey = tempArray;
}else{
data.forEach((item)=>{
if(item.name === "原始文件目录"){
this.isFature = false;
}else{
this.isFature = true;
}
})
}
}
resolve(data);
}else{
this.$message({
type:'error',
message:res.data.message
})
}
})
},
// 脚本文件-懒加载子节点
loadScriptNode(node,resolve){
// console.log(node)
// 从脚本结果页面跳转过来
if(this.$route.query.isExpandShow){
// 如果是默认展开到第三级节点
if(node.level === 0){//根节点
this.queryScriptTables(resolve);
}
else{
this.loadScriptChildNode(node,resolve);
return resolve([]);
}
}else{
// 不是从脚本结果页面跳转而来
if(node.level === 0){//根节点
// 保存脚本节点
this.scriptNode = node;
this.scriptResolve = resolve;
this.queryScriptTables(resolve);
}
if(node.level >= 1){//一级节点及以上
this.loadScriptChildNode(node,resolve)
return resolve([])//防止该节点没有子节点时一直转圈的问题出现
}
}
},
// 脚本文件-获取子节点数据
loadScriptChildNode(node,resolve){
// console.log(node)
this.scriptPath = treeLabel(node);
let params={
extId:parseInt(this.$route.query.leafExtId) ||
parseInt(this.$route.query.resultExtId) || '',
path:this.scriptPath,
level:node.level,
}
getScriptList(params).then((res)=>{
if(res.data.code === 200 ){
let result = res.data.data;
// console.log(result)
if(result){
// 如果是从结果页面跳转过来
if(this.$route.query.isExpandShow){
let tempArray=[];
result.forEach((k)=>{
// 如果是默认展开到第三级节点
if(k.level <= 2){
// 去重
tempArray.forEach((item)=>{
if(item.name === k.name){
return;
}
})
tempArray.push(k);
}
})
this.defaultExpandedKey = tempArray;
}
}
resolve(result)
}else{
this.$message({
type:'error',
message:res.data.message
})
}
}).catch((error)=>{
console.log(error)
})
},
}
三、遇到的问题
懒加载默认展示不到第三级,只是默认展示到根节点
四、原因分析
经过一番调研发现,没有认识到load方法其实就是初始化递归调用接口,加上我写的判断条件有误,导致页面一直卡死
五、解决方案
在load方法获取懒加载孩子节点数据里判断node level小于等于2,把level为2的节点放进defaultExpandedKey里,并且去重。