el-tree 懒加载数据,展开的节点与查询条件联动

目录

效果描述

项目某模块左侧为el-tree树形结构地市数据,右侧有地市查询条件及结果展示

要求:

  1. 点击左侧某地市进行查询时,右侧的地市查询输入框内同步进行赋值(如左侧点击成都,右侧地市查询输入框内,应该自动选中成都)
  2. 同理,右侧地市查询输入框 选中成都时,左侧树形结构成都节点自动展开

实现原理

步骤1:el-tree设置node-key

首先要知道node-key 是设置展开和选中的必要设置,其绑定的值是整个树唯一的(一般绑定 id 等),如果出现重复,会报错。同时设置展开某个节点时,如果这个节点的 id 存在重复,则会出现展开混乱的现象

备注:这里注意,可能在某些特殊时候,后台返回的树形数据,并不存在唯一值(比如我这里,绑定的字段 id ,但在数据里,存在部分数据 id 会一致的情况),这个时候要么是让后端将 id 处理成唯一值,要么就是我们自己对拿到的数据进行处理了(这里我是自己处理的)

步骤2:懒加载时对数据进行处理,给整个树形数据添加唯一值

因为数据量过大,我这里的el-tree用的是懒加载获取数据的方法(:load="loadNode")

html 复制代码
<el-tree
  ref="tree"
  node-key="key"
  accordion
  @node-expand="nodeExpandFn"
  :filter-node-method="filterNode"
  :data="treeData"
  :default-expanded-keys="expanded"
  :props="defaultProps"
  :indent="0"
  lazy
  auto-expand-parent
  highlight-current
  :load="loadNode"
  @node-click="handleNodeClick"
>
</el-tree>

可以看到,node-key 我绑定的是 key 字段 ,这是我给数据中每个对象添加的唯一值:

loadNode方法中,在获取数据时添加唯一值,这里不用关注其他代码,只需关注我根据每个节点的特性,给每个节点对象都增加了一个 key 字段 (我这里第三级的节点数据,每个对象的id是相同的,这也是我选择增加 key 字段的原因)

javascript 复制代码
loadNode(node, resolve) {
 if (node.level === 0) {
   this.resolve = resolve
   this.chooseNode = node
   queryKSHDeviceTree({ type: "0" }).then(res => {
     const treeData = [];
     res.resultValue.forEach(e => {
       e.key = e.id; // key ----------------------
       treeData.push(e);
     });
     resolve(treeData);
   });
 }
 else if (node.level === 1) {
   queryKSHDeviceTree({ type: '1' }).then(res => {
     let treeData = [];
     res.resultValue.forEach(e => {
       e.key = e.id; // key ------------------------
       treeData.push(e);
     });
     resolve(treeData);
   });
 } else if (node.level === 2) {
   queryKSHDeviceTree({ type: '2',pId: node.data.id }).then(res => {
     let treeData = [];
     res.resultValue.forEach(e => {
       // 这里根据当前对象自己的数据,拼出一个唯一值
       e.key = node.data.id + e.pId; // key --------------------
       treeData.push(e);
     });
     resolve(treeData);
   });
 }
}

步骤3:(联动) 点击左侧树形结构,右侧对应查询框自动赋值

这一步相对来说简单一些,在el-tree的点击事件 handleNodeClick 中进行操作

javascript 复制代码
// 如果右侧查询框绑定的字段为 queryForm.cityId
// 点击第二级节点,对其他查询框赋值也同理
handleNodeClick(data, node) {
  if (data.label === "city") {
    this.queryForm.cityId = data.id;
  }
  else if ...
}

步骤4:(联动) 右侧查询条件选择好后,点击查询,左侧树形结构自动展开对应节点

这里 主要用到了 :default-expanded-keys="expanded" (默认展开节点)
expanded 为 存放 key 值的数组

其实当整个树形数据完整,并且设置了 auto-expand-parent 
(展开子节点的时候自动展开父节点)的情况下,
这个时候expanded只用保存最后一级的key值即可

但是,由于我这里的数据是懒加载的,意味着虽然你右侧选了最后一级的数据,点击查询,
但我左侧的树形数据里,还并未加载子级数据,所以这个时候,
即时你将key存入expanded里,它找不到,所以也是没有用的

***所以这个时候,我们需要把每一级要展开的节点key字段都拿到,并存入expanded中
***这样,el-tree在自动展开某一节点时,它会根据懒加载方法,自动获取子节点的数据
***当子节点数据获取到后,它也会将每个节点的key自动去匹配expanded中的值,若存在相同的,
就会接着展开
!!!(简单的说,就是把每一级要展开的节点key字段都拿到,并存入expanded中,
同时懒加载方法写好,其他的交给el-tree自己就行)

经过测试,在展开节点后,对expanded重新赋值,已展开的节点不会自动关闭,所以这里也写了方法,先将el-tree所有的节点进行关闭

javascript 复制代码
// 查询方法
queryClick() {
  let obj = {
    refName: 'tree2',
    cityId: this.queryForm.cityId,
    twoId: this.queryForm.twoId,
    threeId: this.queryForm.threeId || ''
  }
  this.treeNodeLinkage(obj);
}

// 查询条件和el-tree显示联动
// cityId 为第一级id,twoId 为第二级,threeId 为第三级
treeNodeLinkage({refName, cityId, twoId , threeId}) {
  // 先将el-tree所有节点关闭
  let nodesMap = this.$refs[refName].store.nodesMap; // 拿到全部的node
  for(let key in nodesMap) {
    nodesMap[key].expanded = false;
  }
  // 这里的第二级id,对应懒加载方法里 node.level === 2时候
  // 所以这里的newId拼接方法,按照当时key的拼接方法来
  let newId = cityId + twoId;
  this.expanded = [cityId, newId];
  if(threeId) {
    this.expanded.push(threeId);
  }
},

总结

其实这个联动,主要是搞懂el-tree的 node-keydefault-expanded-keys 属性就行。
简单来说,就是你想展开哪个节点,就把该节点node-key对应的字段放入default-expanded-keys对应的数组中。

其他的就是对数据的处理
把接口获取到的数据处理成你想要的样子,这是前端在很多时候都要做的事情

相关推荐
h周杰偷12 分钟前
vue 预览pdf 【@sunsetglow/vue-pdf-viewer】开箱即用,无需开发
前端·vue.js·pdf
小孙姐36 分钟前
3——VUE侦听器和计算属性
前端·javascript·vue.js
好奇的菜鸟1 小时前
typeof 和 as 关键字
javascript·typescript
sususugaa1 小时前
前端框架Vue3——响应式数据,v-on,v-show和v-if,v-for,v-bind
开发语言·前端·vue.js·前端框架
欧阳码农2 小时前
看不懂来打我!Vue3的watch是如何实现数据监听的
vue.js·源码·源码阅读
珹洺3 小时前
从 HTML 到 CSS:开启网页样式之旅(三)—— CSS 三大特性与 CSS 常用属性
前端·javascript·css·网络·html·tensorflow·html5
T^T尚7 小时前
uniapp H5上传图片前压缩
前端·javascript·uni-app
出逃日志8 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
XIE3928 小时前
如何开发一个脚手架
前端·javascript·git·npm·node.js·github
GISer_Jing8 小时前
React渲染相关内容——渲染流程API、Fragment、渲染相关底层API
javascript·react.js·ecmascript