如何实现vue的tree组件


Posted in Vue.js onDecember 03, 2020

前言

Tree一直是大家熟知的组件,做一些大型的后台管理系统都会用到。使用树组件可以完整的展现其中的层级关系,并具有展开收起选择等交互功能。

效果

如何实现vue的tree组件

节点可以无限的递归延伸
可以展开和收起子节点
如果子节点全部选择对应的父节点也应该选中,反之父节点取消选中对应子节点也需要取消选中

API

prop传递data属性,来描述所有的节点的信息

如何实现vue的tree组件

每个节点的配置描述如下

  • title: 展示的标题
  • expand 是否展开节点
  • checked 是否选中节点
  • children 子节点

以及还有两个event

  • on-toggle-expand 展开和收起子列表时触发的
  • on-check-change 点击checkbox触发

我们来 init tree主组件

首先需要考虑一个问题因为tree是递归遍历的,因为我们需要创建一个入口组件还有一个递归children的组件。

首先创建我们的tree组件

如何实现vue的tree组件

如何实现vue的tree组件

我们在初始化以及watch监听的时候重新深拷贝了一下prop传来的data并赋值给了cloneData

然后在template里来引入node.vue,然后循环cloneData来循环node.vue。node.vue接受两个prop

showCheckbox 就是tree组件接收的 showCheckbox 这里传给node组件来判断展示
data 为item 是一个object 负责渲染当前节点,如果当前节点有children 那就递归调用本身来递归渲染
这是使用了一个deepCopy的方法,这个是深拷贝的简单实现,递归的去重新重新赋值data数组,开辟新的堆内存与传入的数据无关联。不会破坏原有的数据

我们来 init node递归组件

node组件为主要组件,主要功能是展示当前项的title 以及 如果有children时递归本身。

  • 展开关闭按钮
  • checkbox
  • 节点的title
  • 递归

node的基本构造

如何实现vue的tree组件

prop中的data就是当前节点的所有信息,比如说是否展开和关闭当前的节点,是否选中,title标题以及children的子节点数组。

  • expand 判断条件为 data.children &&  data.children.length 才会展示 + 或者 - 按钮
  • checkbox就是当前的节点是否需要默认勾选

点击 + 号时会展开当前的子节点,点击 - 号会关闭,这一步只需要在handleExpand 中修改data的expand数据即可同时我们还需要触发一个emit来提示用户展示或者收起了节点

如何实现vue的tree组件

如何实现vue的tree组件

这里有一点需要注意 修改data.expand我们通过 VUE的 $set 并没有像下面这样

this.data.expand = !this.data.expand;

这里有什么区别呢?如果直接用上面的代码进行修改,就会发现数据虽然被修改了,但是视图没有被更新,这是因为这里的this.data 时props通过上一级传递出来的,也有可能时node递归传递的,无论如何咱们需要的cloneData里的节点数据,此时不一定初始化定义时就含有expand或者checked字段 如果不含有直接通过this.data.expand修改,这个expand时不可响应式的数据,所以视图不会被更新,干脆就直接用$set来改变

接下来我们就需要处理响应状态了,大家可能觉得不就是选中和取消吗 的确这样可以,但是树组件时有上下级关系,他们分为两种逻辑,当选中(或取消选中)一个节点时

  • 它下面的所有子节点都会被选中
  • 如果同一级所有子节点选中时,它的父级也自动选中,一直递归判断到根节点。

第 1 个逻辑相对简单,当选中一个节点时,只要递归地遍历它下面所属的所有子节点数据,修改所有的 checked 字段即可

如何实现vue的tree组件

再来看第2个逻辑 一个节点,除了手动选中(或反选),还有就是第 2 种逻辑的被动选中(或反选),也就是说,如果这个节点的所有直属子节点(就是它的第一级子节点)都选中(或反选)时,这个节点就自动被选中(或反选),递归地,可以一级一级响应上去。有了这个思路,我们就可以通过 watch 来监听当前节点的子节点是否都选中,进而修改当前的 checked 字段:

如何实现vue的tree组件

在 watch 中,监听了 data.children 的改变,并且是深度监听的。这段代码的意思是,当 data.children 中的数据的某个字段发生变化时(这里当然是指 checked 字段),也就是说它的某个子节点被选中(或反选)了,这时执行绑定的句柄 handler 中的逻辑。const checkedAll = !data.some(item => !item.checked); 也是一个巧妙的缩写,checkedAll 最终返回结果就是当前子节点是否都被选中了。

这里非常巧妙地利用了递归的特性,因为 node.vue 是一个递归组件,那每一个组件里都会有 watch 监听 data.children,要知道,当前的节点有两个”身份“,它既是下属节点的父节点,同时也是上级节点的子节点,它作为下属节点的父节点被修改的同时,也会触发上级节点中的 watch 监听函数。这就是递归。

结语

递归的可以把一个大问题通过不断调用自身的方式,使代码简洁的实现功能,但是个别问题像算法中斐波那契数列如果使用递归就会使得时间复杂度以及空间复杂度会飙升。总的来说要合理运用,活学活用。

以上就是如何实现vue的tree组件的详细内容,更多关于vue tree组件的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue+vant实现购物车全选和反选功能
Nov 17 Vue.js
vue单元格多列合并的实现
Nov 26 Vue.js
vue祖孙组件之间的数据传递案例
Dec 07 Vue.js
vue 数据操作相关总结
Dec 17 Vue.js
vue项目如何监听localStorage或sessionStorage的变化
Jan 04 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
vue如何使用rem适配
Feb 06 Vue.js
VUE实现吸底按钮
Mar 04 Vue.js
开发一个封装iframe的vue组件
Mar 29 Vue.js
vue3使用vue-router的完整步骤记录
Jun 20 Vue.js
vue 数字翻牌器动态加载数据
Apr 20 Vue.js
Vue实现图书管理小案例
Dec 03 #Vue.js
Vue router安装及使用方法解析
Dec 02 #Vue.js
vue3.0中setup使用(两种用法)
Dec 02 #Vue.js
vue3.0+vue-router+element-plus初实践
Dec 02 #Vue.js
Vue router传递参数并解决刷新页面参数丢失问题
Dec 02 #Vue.js
详解Vue3 Teleport 的实践及原理
Dec 02 #Vue.js
vue $router和$route的区别详解
Dec 02 #Vue.js
You might like
php 小乘法表实现代码
2009/07/16 PHP
php 验证码制作(网树注释思想)
2009/07/20 PHP
PHP通过CURL实现定时任务的图片抓取功能示例
2016/10/03 PHP
JavaScript中的this实例分析
2011/04/28 Javascript
webapp框架AngularUI的demo改造之路
2014/12/21 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
JavaScript判断对象是否为数组
2015/12/22 Javascript
jquery拖动层效果插件用法实例分析(附demo源码)
2016/04/28 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
详解AngularJS中$filter过滤器使用(自定义过滤器)
2017/02/04 Javascript
js下载文件并修改文件名
2017/05/08 Javascript
Vue2 使用 Echarts 创建图表实例代码
2017/05/18 Javascript
React入门教程之Hello World以及环境搭建详解
2017/07/11 Javascript
vue axios登录请求拦截器
2018/04/02 Javascript
node实现分片下载的示例代码
2018/10/17 Javascript
js中的闭包实例展示
2018/11/01 Javascript
JS实现的合并两个有序链表算法示例
2019/02/25 Javascript
微信小程序实现音乐播放器
2019/11/20 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
解决vue项目中出现Invalid Host header的问题
2020/11/17 Javascript
vue组件是如何解析及渲染的?
2021/01/13 Vue.js
在Python中处理时间之clock()方法的使用
2015/05/22 Python
python kmeans聚类简单介绍和实现代码
2018/02/23 Python
django使用LDAP验证的方法示例
2018/12/10 Python
Python图像处理之图像的读取、显示与保存操作【测试可用】
2019/01/04 Python
Pytorch to(device)用法
2020/01/08 Python
美国知名的摄影器材销售网站:Adorama
2017/02/01 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
宝宝周岁宴答谢词
2014/01/26 职场文书
2014市国税局对照检查材料思想汇报
2014/09/23 职场文书
群众路线专项整治工作情况报告
2014/10/28 职场文书
2015年学生会工作总结范文
2015/03/31 职场文书
春季运动会加油词
2015/07/18 职场文书
小学运动会入场词
2015/07/18 职场文书
关于五一放假的通知
2015/08/18 职场文书
婚前协议书怎么写,才具有法律效力呢 ?
2019/06/28 职场文书