如何实现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 element实现表格合并行数据
Nov 30 Vue.js
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
vue中watch的用法汇总
Dec 28 Vue.js
vue实现验证用户名是否可用
Jan 20 Vue.js
vue实现简易计算器功能
Jan 20 Vue.js
vue基于Teleport实现Modal组件
May 31 Vue.js
Vue提供的三种调试方式你知道吗
Jan 18 Vue.js
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
VUE之图片Base64编码使用ElementUI组件上传
Apr 09 Vue.js
vue实力踩坑之push当前页无效
Apr 10 Vue.js
vue3种table表格选项个数的控制方法
Apr 14 Vue.js
vue3不同环境下实现配置代理
May 25 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控制linux服务器常用功能 关机 重启 开新站点等
2012/09/05 PHP
php通过分类列表产生分类树数组的方法
2015/04/20 PHP
使用PHP如何实现高效安全的ftp服务器(二)
2015/12/30 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
javascript奇异的arguments分析
2010/10/20 Javascript
location对象的属性和方法应用(解析URL)
2013/04/12 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
Javascript核心读书有感之语句
2015/02/11 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
2015/12/04 Javascript
javascript之Array 数组对象详解
2016/06/07 Javascript
web前端开发upload上传头像js示例代码
2016/10/22 Javascript
原生JS实现隐藏显示图片 JS实现点击切换图片效果
2021/01/27 Javascript
基于对象合并功能的实现示例
2017/10/10 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
2017/10/25 Javascript
详解Angular6.0使用路由步骤(共7步)
2018/06/29 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
2019/04/10 jQuery
原生js实现each方法实例代码详解
2019/05/27 Javascript
纯 JS 实现放大缩小拖拽功能(完整代码)
2019/11/25 Javascript
js正则表达式简单校验方法
2021/01/03 Javascript
[00:32]2016完美“圣”典风云人物:Maybe宣传片
2016/12/05 DOTA
VSCode Python开发环境配置的详细步骤
2019/02/22 Python
Django 开发环境配置过程详解
2019/07/18 Python
Python Des加密解密如何实现软件注册码机器码
2020/01/08 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
Raleigh兰令自行车美国官网:英国凤头牌自行车
2018/01/08 全球购物
7 For All Mankind官网:美国加州洛杉矶的高级牛仔服装品牌
2018/12/20 全球购物
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
护理自荐信
2013/10/22 职场文书
《问银河》教学反思
2014/02/19 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
应用外语系自荐信
2014/06/26 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
股东合作协议书模板2篇
2019/11/05 职场文书
python自动化测试通过日志3分钟定位bug
2021/11/20 Python