怎么使用vue el-tree实现懒加载数据和树的过滤
vue el-tree懒加载数据并且实现树的过滤
树的样式:

过滤效果:

过滤代码实现:
1,如果这里的树数据是全加载,即可使用element-ui中的设置,进行前端过滤。
element-ui对应的组件位置
// 监听输入框中的数据 watch: { filterText(val) { this.$refs.tree.filter(val); } }, methods: { filterNode(value, data) { if (!value) return true; return data.label.indexOf(value) !== -1; } },
2,如果这里的树数据是懒加载,,需要使用后端的模糊加载,返回搜索到的树的节点。
重要的是:filter-node-method=“filterNode”,这个属性
data(){ return { filterText: '', keyword:'', } } watch: { // 树节点的过滤 filterText(val) { this.keyword = val this.getTreeData() } methods:{ // 将keyword传入到接口中,从后端返回模糊匹配后的节点,然后赋值给树绑定的数据变量,即可完成。 // 得到树的列表 async getTreeData() { const param = { type: Number(this.cateTabActive), keyword: this.keyword }; const res = await this.$api.get('/api/category', param); if (res.code == 200) { this.treeData = res.info; } else { return false; } }, }
Element el-tree懒加载问题
本文章项目项目全程使用Vue2和Element2!
懒加载:点击节点时才进行该层数据的获取。
注意:使用了懒加载之后,一般情况下就可以不用绑定:data。
基础使用
懒加载需要再指定一个lazy和懒加载数据的方法:load:
懒加载的方法会得到两个参数,一个是获取的当前节点(node)的信息(包括它的层级数据等);另一个是一个重新渲染当前节点下子节点的方法(resolve),它接收一个数组,该数组也会按照props中的映射关系,进行显示。
注意:懒加载的方法(:load)在初始载入时执行一次,而后每次点击节点前面的箭头获取子节点的时候再次触发;即使初始载入的数据有变换也不会再触发,点击展开子节点后再次点击收缩节点时也不会再触发!!
由于懒加载是一级一级往下获取,所以对每一级来说都要使用resolve来渲染它显示的子节点,如果该节点下没有显示的内容,它则会一直转圈,这个时候需要设置resolve返回一个空数组,这样如果它没有获取到子节点的内容则会在转圈之后显示为空(并去掉前面的向下展开的箭头),不会一直转圈:
return resolve([]);
现实场景:可以在通过node取到每一层的id,根据这个id调用接口得到数据。再通过resolve进行回显,回显的数据为这个id的子节点
二次封装
场景:由于用到树形控件的地方很多,而且需要显示的数据都不一样,所以将树形控件再封装一层,然后根据外部组件传来的不同参数,进行树形图的不同显示。
思路:通过监听外部传入数据的变化,重新渲染树,完成不同数据的显示;但是:load只会初始加载一次并获取当前绑定树上node,如果后面监听数据的时候再次调用loadTree是获取不到它的node和resolve,所以会导致渲染失败。这个时候可以通过:data显示数据,当我们树上有节点时,就可以正常触发:load进行子节点的懒加载了。具体实现如下:
数据回显
场景:在懒加载的树上设置复选框,需要将之前添加好的懒加载选中的部分在表格的编辑中回显出来。
思路:由于懒加载的数据是一级一级获取的,所以可以利用default-expanded-keys和default-checked-keys属性,将需要进行回显的节点在渲染树的时候就设置上去。(注意在使用这两个属性的时候)
回显问题
场景:在使用懒加载进行数据回显时,当添加选中的数据里存在以下情况:一个父节点下的第一和第二个子节点同时被选中,回显时得到的默认选中的节点数组里也只有这两个节点的id,但是最终懒加载回显的数据是这个父节点下的所有子节点全都被选中(获取其他类似情况)。
分析:由于懒加载的树是异步加载的,树在判断子节点是否选中的时候可能由于选中的子节点,而导致其父节点因为关联而被计算判断出选中。
解决一:如果不需要父节点的复选框,或者父节点没有复选框,只有子节点有,或者不需要父子节点关联的情况下,可以使用check-strictly属性,断开父子之间的连接:
解决二:对选中节点的回显不使用default-checked-keys,而是利用$nextTick和setCheckedKeys设置节点的选中,此方法必须设置node-key属性:
注意:该方法因为在load方法中,所以每次触发load的时候(每次首次下拉节点)都会重新获取一边数据,这会导致之前可能选中的节点又被回显节点重置了。
这种情况如果在层级没有超过2级时,可以通过设置一个计数器,让这个$nextTick只执行一次,但是如果层级过多,下层还是会出现全选的情况。这个问题我暂时无法避免,所以综合考虑下来还是采用每执行一次load就执行一次$nextTick,这样可以保证更深的层级节点能正确显示,对于回显编辑来说,只要做到先下拉节点再选择,就不会出错了。
复选框显隐
场景:现在需要去掉所有的叶子节点(没有子节点的节点)的复选框,默认选中了父节点则其下所有子节点都 不做判断。
思路:由于element的tree并未提供这个属性或方法,需要我们自己手动去修改element内部代码,然后再重新打包,将打好的包替换自己项目中element里的ilb文件夹:
将对应版本的element源码下载下来,安装依赖并查看项目是否启动成功:
npm install npm run dev
运行成功后找到packages/tree/src/tree-node修改源码:
......
源码修改好之后,进行打包:
npm run dist
打包完成之后会得到新的lib文件夹,将其替换自己项目中的对应位置的lib文件夹即可。
注意:直接修改自己项目中的packages里的代码是无效的,因为项目中所运行的是lib文件夹里的,packages只是方便查看内部源码!