如何实现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项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
vue开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 Vue.js
jenkins自动构建发布vue项目的方法步骤
Jan 04 Vue.js
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
Jan 08 Vue.js
Vue 实现可视化拖拽页面编辑器
Feb 01 Vue.js
vue中h5端打开app(判断是安卓还是苹果)
Feb 26 Vue.js
详解vue3中组件的非兼容变更
Mar 03 Vue.js
vue路由实现登录拦截
Mar 24 Vue.js
Vue如何实现组件间通信
May 15 Vue.js
Vue Element UI自定义描述列表组件
May 18 Vue.js
VUE解决跨域问题Access to XMLHttpRequest at
May 06 Vue.js
Vue router配置与使用分析讲解
Dec 24 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实现分页显示
2015/11/03 PHP
解决window.opener=null;window.close(),只支持IE6不支持IE7,IE8的问题
2014/01/14 Javascript
jQuery实现的原图对比窗帘效果
2014/06/15 Javascript
IE下通过a实现location.href 获取referer的值
2014/09/04 Javascript
javascript中2个感叹号的用法实例详解
2014/09/04 Javascript
深入探讨javascript函数式编程
2015/10/11 Javascript
JavaScript运行过程中的“预编译阶段”和“执行阶段”
2015/12/16 Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
2016/11/20 Javascript
详解浏览器渲染页面过程
2017/02/09 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
2018/05/04 Javascript
layui按条件隐藏表格列的实例
2019/09/19 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
微信小程序工具函数封装
2019/10/28 Javascript
vue使用video插件vue-video-player的示例
2020/10/03 Javascript
基于JavaScript实现简单抽奖功能代码实例
2020/10/20 Javascript
在Python下尝试多线程编程
2015/04/28 Python
python读取Excel实例详解
2018/08/17 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
2019/07/31 Python
python实现登录密码重置简易操作代码
2019/08/14 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
2020/01/09 Python
在keras中获取某一层上的feature map实例
2020/01/24 Python
python微信公众号开发简单流程实现
2020/03/09 Python
Python urllib2运行过程原理解析
2020/06/04 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
如何创建一个Flask项目并进行简单配置
2020/11/18 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
英国演唱会订票网站:Ticket Selection
2018/03/27 全球购物
英国在线发型和美容产品商店:Beauty Cutie
2019/04/27 全球购物
酷瑞网络科技面试题
2012/03/30 面试题
JAVA程序设计笔试题面试题一套
2015/07/28 面试题
行政部主管岗位职责
2013/12/28 职场文书
财务会计专业自荐书
2014/06/30 职场文书
乡镇组织委员个人整改措施
2014/09/16 职场文书
秋冬农业生产标语
2014/10/09 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
mysql的MVCC多版本并发控制的实现
2021/04/14 MySQL