如何实现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动态合并单元格并添加小计合计功能示例
Nov 26 Vue.js
vue中defineProperty和Proxy的区别详解
Nov 30 Vue.js
用vue设计一个日历表
Dec 03 Vue.js
Vue中computed和watch有哪些区别
Dec 19 Vue.js
vue 实现click同时传入事件对象和自定义参数
Jan 29 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
Feb 20 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
Apr 17 Vue.js
Vue如何清空对象
Mar 03 Vue.js
vue cli4中mockjs在dev环境和build环境的配置详情
Apr 06 Vue.js
vue实现书本翻页动画效果实例详解
Apr 08 Vue.js
vue项目proxyTable配置和部署服务器
Apr 14 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
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
如何用php获取文件名后缀
2013/06/09 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
禁止F5等快捷键的JS代码
2007/03/06 Javascript
把JS与CSS写在同一个文件里的书写方法
2007/06/02 Javascript
IE无法设置短域名下Cookie
2010/09/23 Javascript
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
javascript学习笔记(十八) 获得页面中的元素代码
2012/06/20 Javascript
jQuery数据缓存功能的实现思路及简单模拟
2013/05/27 Javascript
javaScript函数中执行C#代码中的函数方法总结
2013/08/07 Javascript
js中的this关键字详解
2013/09/25 Javascript
js控制表单不能输入空格的小例子
2013/11/20 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
Javascript中字符串replace方法的第二个参数探究
2016/12/05 Javascript
从零学习node.js之详解异步控制工具async(八)
2017/02/27 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
微信小程序实现弹出菜单
2018/07/19 Javascript
node中的session的具体使用
2018/09/14 Javascript
bootstrap table.js动态填充单元格数据的多种方法
2019/07/18 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
使用Python实现windows下的抓包与解析
2018/01/15 Python
python构建深度神经网络(续)
2018/03/10 Python
PyQt5每天必学之进度条效果
2018/04/19 Python
Python判断中文字符串是否相等的实例
2018/07/06 Python
Python函数中不定长参数的写法
2019/02/13 Python
详解Python的循环结构知识点
2019/05/20 Python
python3正则模块re的使用方法详解
2020/02/11 Python
Silk’n激光脱毛器官网:silkn.com
2016/10/06 全球购物
党员批评与自我批评(5篇)
2014/09/23 职场文书
小平您好观后感
2015/06/09 职场文书
小学生暑假安全保证书
2015/07/13 职场文书
关于Numpy之repeat、tile的用法总结
2021/06/02 Python
React自定义hook的方法
2022/06/25 Javascript