如何实现vue的tree组件
作者:Yaning 发布时间:2024-05-09 15:17:32
前言
Tree一直是大家熟知的组件,做一些大型的后台管理系统都会用到。使用树组件可以完整的展现其中的层级关系,并具有展开收起选择等交互功能。
效果
节点可以无限的递归延伸
可以展开和收起子节点
如果子节点全部选择对应的父节点也应该选中,反之父节点取消选中对应子节点也需要取消选中
API
prop传递data属性,来描述所有的节点的信息
每个节点的配置描述如下
title: 展示的标题
expand 是否展开节点
checked 是否选中节点
children 子节点
以及还有两个event
on-toggle-expand 展开和收起子列表时触发的
on-check-change 点击checkbox触发
我们来 init tree主组件
首先需要考虑一个问题因为tree是递归遍历的,因为我们需要创建一个入口组件还有一个递归children的组件。
首先创建我们的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的基本构造
prop中的data就是当前节点的所有信息,比如说是否展开和关闭当前的节点,是否选中,title标题以及children的子节点数组。
expand 判断条件为 data.children && data.children.length 才会展示 + 或者 - 按钮
checkbox就是当前的节点是否需要默认勾选
点击 + 号时会展开当前的子节点,点击 - 号会关闭,这一步只需要在handleExpand 中修改data的expand数据即可同时我们还需要触发一个emit来提示用户展示或者收起了节点
这里有一点需要注意 修改data.expand我们通过 VUE的 $set 并没有像下面这样
this.data.expand = !this.data.expand;
这里有什么区别呢?如果直接用上面的代码进行修改,就会发现数据虽然被修改了,但是视图没有被更新,这是因为这里的this.data 时props通过上一级传递出来的,也有可能时node递归传递的,无论如何咱们需要的cloneData里的节点数据,此时不一定初始化定义时就含有expand或者checked字段 如果不含有直接通过this.data.expand修改,这个expand时不可响应式的数据,所以视图不会被更新,干脆就直接用$set来改变
接下来我们就需要处理响应状态了,大家可能觉得不就是选中和取消吗 的确这样可以,但是树组件时有上下级关系,他们分为两种逻辑,当选中(或取消选中)一个节点时
它下面的所有子节点都会被选中
如果同一级所有子节点选中时,它的父级也自动选中,一直递归判断到根节点。
第 1 个逻辑相对简单,当选中一个节点时,只要递归地遍历它下面所属的所有子节点数据,修改所有的 checked 字段即可
再来看第2个逻辑 一个节点,除了手动选中(或反选),还有就是第 2 种逻辑的被动选中(或反选),也就是说,如果这个节点的所有直属子节点(就是它的第一级子节点)都选中(或反选)时,这个节点就自动被选中(或反选),递归地,可以一级一级响应上去。有了这个思路,我们就可以通过 watch 来监听当前节点的子节点是否都选中,进而修改当前的 checked 字段:
在 watch 中,监听了 data.children 的改变,并且是深度监听的。这段代码的意思是,当 data.children 中的数据的某个字段发生变化时(这里当然是指 checked 字段),也就是说它的某个子节点被选中(或反选)了,这时执行绑定的句柄 handler 中的逻辑。const checkedAll = !data.some(item => !item.checked); 也是一个巧妙的缩写,checkedAll 最终返回结果就是当前子节点是否都被选中了。
这里非常巧妙地利用了递归的特性,因为 node.vue 是一个递归组件,那每一个组件里都会有 watch 监听 data.children,要知道,当前的节点有两个”身份“,它既是下属节点的父节点,同时也是上级节点的子节点,它作为下属节点的父节点被修改的同时,也会触发上级节点中的 watch 监听函数。这就是递归。
结语
递归的可以把一个大问题通过不断调用自身的方式,使代码简洁的实现功能,但是个别问题像算法中斐波那契数列如果使用递归就会使得时间复杂度以及空间复杂度会飙升。总的来说要合理运用,活学活用。
来源:https://juejin.cn/post/6901510486773202951?utm_source=tuicool&utm_medium=referral
猜你喜欢
- 编写程序的时候,经常要处理字符串,最基本就是字符串的查找,在php检测字符串中是否包含指定字符串可以使用正则,如果你对正则不了解,那么有几个
- 功能:获取android设备中某一个app的cpu和内存环境:python和adb使用方法:使用adb连接android设备,打开将要测试的
- 如下所示:#coding=utf8import csv import logginglogging.basicConfig(level=lo
- 1. 概念显著性检测,就是使用图像处理技术和计算机视觉算法来定位图片中最“显著”的区域。显著区域就是
- 前几天,我们用虚拟机安装了Ubuntu 20.04。今天,我们来安装一些常用的工具,比如Pycharm。 Pycharm是一种用来开发Pyt
- 了解算法之前,我们先看一下什么是算法定义:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用
- 近几天闲着没事开始学了些python,看了看之前写过的代码,把写过的基础的几个程序写进博客,今天是第一个。一个可以说简单的不能再简单的小程序
- def Dijkstra(network,s,d):#迪杰斯特拉算法算s-d的最短路径,并返回该路径和代价 print(&quo
- 用下列代码判断表单提交到服务器的数据是否有谈话内容,如果没有的话就不作处理了:if len(usersays)<>0&
- 引言膨胀与腐蚀是图像处理中两种最基本的形态学操作,膨胀将目标点融合到背景中,向外部扩展,腐蚀与膨胀意义相反,消除连通的边界,使边界向内收缩。
- 先来看看js中的Null类型表示什么?null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象,一般一个未定义的变量在初次使用
- 三元运算又称三目运算,是对简单的条件语句的简写简单条件语句:if 条件成立: val = 1else: val =
- 目录前言什么是 websocketwebsocket 通信原理和机制websocket 的特点构建实时日志跟踪的小例子前言websocket
- 首先简单介绍使用vue-router的四个基本步骤:(为了方便演示,所有代码都写在一个文件里)1.定义组件2.定义路由3.创建router实
- 函数初解function,是一种语法结构,将实现某一个功能的代码块(多行代码)封装到一个结构中实现代码的重复利用函数定义语法:关键点:fun
- 本文实例讲述了Python基于有道实现英汉字典功能的方法。分享给大家供大家参考。具体如下:import re,urllibaa="
- centos7之Python3.74安装安装版本:Python3.74系统版本:centos7系统默认安装Python2.7,保留。安装/u
- 系统环境为server20121、下载mysql解压版,解压安装包到指定目录2、在以上目录中,复制一份my-default.ini文件,重命
- 1、#coding:utf-8chose = [ ('foo',1,2), ('bar
- 什么是RC4算法呢?也许您还不知道,没关系我为您找了下相关资料方便大家查看;RC4加密算法 RC4加密算法是大名鼎鼎的RSA三人组