vue2实现一个树型控件(支持展开树与checkbox勾选)

目录

  • vue2实现一个树型控件(支持展开树与checkbox勾选)
    • TreeItem.vue
    • Tree.vue
    • 效果

vue2实现一个树型控件(支持展开树与checkbox勾选)

TreeItem.vue

<template><div class="tree-item"><span @click="toggleExpanded" class="icon" v-show="treeNode && treeNode.children && treeNode.children.length"><spanclass="triangle":class="[ expanded ? 'triangle_down' : 'triangle_up']"></span></span><span class="icon-font icon-kaiwenjianjia-shense icon-wenjianjia"></span><span @click="toggleExpanded">{{ treeNode.deptName }}</span><input class="check-item check-style" type="checkbox" v-model="treeNode.checked" @change="handleChange(treeNode)"><div class="children" v-show="expanded"><TreeItem v-for="childNode in treeNode.children" :key="childNode.id" :tree-node="childNode" @checkItem="handleChange"></TreeItem></div></div>
</template><script>
export default {name: 'TreeItem',props: {// 每一项的节点数据treeNode: {type: Object,required: true}},data() {return {// 是否展开expanded: false,};},methods: {toggleExpanded() {this.expanded = !this.expanded;},handleChange(item) {console.log('handleChange',item, "treeNode",this.treeNode);this.setChecked(item,item.checked);this.$emit('checkItem',item)},// 递归 当父集选中或者取消 联动子集setChecked(node, checked) {node.checked = checked;if (node.children && node.children.length > 0) {for (let child of node.children) {this.setChecked(child, checked);}}}}
};
</script><style lang="less" scoped>
.tree-item {position: relative;font-size: 14px;.check-item {position: absolute;top: 10px;right: 4px;z-index: 111;cursor: pointer;}
}
.icon {width: 16px;display: inline-block;margin-right: 4px;line-height: 20px;cursor: pointer;
}
.icon-wenjianjia {color: #ccc;margin-right: 6px;
}
.children {margin-left: 20px;
}
input[type="checkbox"] {/* 未选中时的样式 */appearance: none;border: 1px solid transparent;width: 14px;height: 14px;display: inline-block;position: relative;vertical-align: middle;cursor: pointer;background-color: #eee;
}/* 选中时的样式 */
input[type="checkbox"]:checked {background-color: #1bc5bd;
}/* ✔图标 */
input[type="checkbox"]:checked:after {content: "✔";position: absolute;left: 1px;top: -11px;font-size: 12px;color: #fff;
}
.triangle {position: relative;top: -4px;transition: 0.5s;
}
.triangle_up {display: inline-block;margin: 0px;width: 0px;height: 0px;border-left: 4px solid transparent;border-right: 4px solid transparent;border-bottom: 4px solid #ccc;
}
.triangle_down {display: inline-block;margin: 0px;width: 0px;height: 0px;border-left: 4px solid transparent;border-right: 4px solid transparent;border-top: 4px solid #ccc;
}
</style>

Tree.vue

<template><div class="select-tree-com"><TreeItemclass="tree-item" v-for="treeNode in treeData" :key="treeNode.id" :tree-node="treeNode"@checkItem="checkItem"></TreeItem></div>
</template><script>
import TreeItem from "./TreeItem"
export default {name:'SelectTreeCom',components:{TreeItem},props: {// 结构数据lists: {type: Array,default () {return []}},// 是否开启checkboxcheckbox: {type: Boolean,default: false},},data() {return {treeData: [{id: 1,name: 'Node 1',deptCode:1,deptName:'Node-1',checked: false,children: [{id: 11,deptCode:11,deptName:'Node-11',parentId: 1,name: 'Node 11',checked: false,children: [{id: 111,deptName:'Node-111',deptCode:111,parentId: 11,name: 'Node 111',checked: false,children: [{id: 1111,deptName:'Node-1111',deptCode:1111,parentId: 111,name: 'Node 1111',checked: false,children: []},{id: 1112,deptName:'Node-1112',deptCode:1112,parentId: 111,name: 'Node 1112',checked: false,children: []}]},{id: 112,deptName:'Node-112',deptCode:112,parentId: 11,name: 'Node 112',checked: false,children: []}]},{id: 12,deptName:'Node-12',deptCode:12,parentId: 1,name: 'Node 12',checked: false,children: []},{id: 13,deptName:'Node-13',deptCode:13,parentId: 1,name: 'Node 13',checked: false,children: [{id: 131,deptName:'Node-131',deptCode:131,parentId: 13,name: 'Node 131',checked: false,children: [{id: 1311,deptName:'Node-1311',deptCode:1311,parentId: 131,name: 'Node 1311',checked: false,children: []},{id: 1312,deptName:'Node-1312',deptCode:1312,parentId: 131,name: 'Node 1312',checked: false,children: []}]},{id: 132,deptName:'Node-132',deptCode:132,parentId: 13,name: 'Node 132',checked: false,children: []}]},]},{id:2,deptName:'Node-2',deptCode:2,name: 'Node 2',checked: false,children: []}],// treeData: [],// 选中的所有项 check为truecheckList:[],};},watch:{lists:{handler(newV){console.log('selectTreeeCom组件lists',newV);// this.treeData = [...newV]},// immediate: true}},created() {},methods: {// 拿到当前选中的所有item数据checkItem(item) {// console.log('selectcom-checkItem',item);let newArr = []newArr = this.flattenNodes(item)console.log('newArr',newArr);// 存储选中的!newArr && newArr.length && newArr.forEach(item => {if ( item.checked ) {this.checkList.push(item)}});console.log('存储选中的-this.checkList',this.checkList);// 处理再一次选中时 包含之前的选项,覆盖之前的选项 checkthis.checkList && this.checkList.length && this.checkList.forEach(itemB =>{newArr.some(itemA => {if ( itemA.id === itemB.id ) {itemB.checked = itemA.checked}})})console.log('处理this.checkList',this.checkList);// 过滤掉 check为false 得到实际选中的数据this.checkList = this.checkList.filter(item=>{if(item.checked) {return item;}})// console.log('res-this.checkList',this.checkList);// 去重let uniqueArr = []uniqueArr = Array.from(new Set(this.checkList.map(item => item.id))).map(id => this.checkList.find(item => item.id === id));console.log('uniqueArr',uniqueArr);this.$emit('getCheckList', uniqueArr)},// 把树对象 扁平化为父+子的数据flattenNodes(data) {let nodes = [];// 添加当前节点到结果数组中nodes.push({id: data.id,name: data.name,checked: data.checked,deptCode: data.deptCode,deptName: data.deptName});// 遍历子级节点并递归处理if (data.children && data.children.length > 0) {for (let child of data.children) {nodes = nodes.concat(this.flattenNodes(child));}}return nodes;},// 全选setCheckAll(params){// console.log('setCheckAll',params);const allTreeData = this.treeToOneArr(this.treeData)if ( params ) {this.checkList = [...allTreeData]return this.checkList} else {this.checkList = []return this.checkList}},// 取消全选cancelCheckAll(){this.checkList = []},// tree数据 扁平化treeToOneArr(arr) {const data = JSON.parse(JSON.stringify(arr))const newData = []const hasChildren = item => {(item.children || (item.children = [])).map(v => {hasChildren(v)})delete item.childrennewData.push(item)}data.map(v => hasChildren(v))return newData},oneArrToTree(data) {// 对源数据深度克隆const cloneData = JSON.parse(JSON.stringify(data))// filter嵌套filter相当于for循环嵌套for循环const result = cloneData.filter(parent => {// 返回每一项的子级数组const branchArr = cloneData.filter(child => parent.parentCode === child.parentCode)// 若子级存在,则给子级排序;且,赋值给父级if (branchArr.length > 0) {branchArr.sort(this.compare('order'))parent.children = branchArr}// 返回最高的父级,即,parent_id为0,return parent.parentCode === '00'})// 给最高级的父级排序result.sort(this.compare('order'))return result},// 对象数组排序compare(property) {return function(a, b) {const value1 = a[property]const value2 = b[property]return value1 - value2// 升序,降序为value2 - value1}},}};
</script><style lang="less" scoped>
.select-tree-com {padding: 10px 0;
}
.tree-item {line-height: 34px;}
</style>

效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel Dashboard集成Nacos

1.前言 当项目上Sentinel Dashboard做流量监控的时候&#xff0c;我们可以通过Sentinel控制台修改限流配置&#xff0c;但当我们使用Nacos作为配置中心动态配置流控规则的时候&#xff0c;问题就来了。 首先我们要明白&#xff0c;Sentinel Dashboard的配置是从机器的内存中加…

TCP网络通信编程之网络上传文件

【图片】 【思路解析】 【客户端代码】 import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;/*** ProjectName: Study* FileName: TCPFileUploadClient* author:HWJ* Data: 2023/7/29 18:44*/ public class TCPFil…

【论文简述】DIP: Deep Inverse Patchmatch for High-Resolution Optical Flow(CVPR 2022)

一、论文简述 1. 第一作者&#xff1a;Rui Li 2. 发表年份&#xff1a;2023 3. 发表期刊&#xff1a;CVPR 4. 关键词&#xff1a;光流、深度学习、PatchMatch、局部搜索 5. 探索动机&#xff1a;对于深度学习来说&#xff0c;除了准确性之外&#xff0c;性能和内存也是一个…

基于深度学习的CCPD车牌检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于CCPD数据集的高精度车牌检测系统可用于日常生活中检测与定位车牌目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的车牌目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集…

回归预测 | MATLAB实现GRNN广义回归神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现GRNN广义回归神经网络多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现GRNN广义回归神经网络多输入单输出回归预测(多指标,多图)效果一览基本介绍程序设计参考资料效果一览 基本介绍 MATLAB实现GRNN广义回归神经网络多输入单输出回归…

GitLab备份升级

数据备份(默认的备份目录在/var/opt/gitlab/backups/下&#xff0c;生成一个以时间节点命名的tar包。) gitlab-rake gitlab:backup:create新建repo源&#xff0c;升级新版本的gitlab vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] namegitlab-ce baseurlhttps://mirrors.…

解决el-table打印时数据重复显示

1.表格数据比较多加了横向滚动和竖向滚动&#xff0c;导致打印出问题 主要原因是fixed导致&#xff0c;但是又必须得滚动和打印 方法如下&#xff1a; 1. 2. is_fixed: true,//data中定义初始值 3.打印时设置为false,记得要改回true if (key 2) { this.is_fixed false //打…

虹科活动 | 走进宇通客车-汽车新供应链技术展精彩回顾

引言 7月27日&#xff0c;走进宇通客车-汽车新供应链技术展于宇通研发中心成功举办&#xff0c;本次展会中虹科为大家带来了一体化车载天线与车辆GNSS仿真测试方案&#xff0c;感谢您前来探讨与交流&#xff01; 精彩产品一览 车辆GNSS仿真测试方案 虹科高性能GNSS模拟器具有灵…

Eureka 学习笔记3:EurekaHttpClient

版本 awsVersion ‘1.11.277’ EurekaTransport 用于客户端和服务端之间进行通信&#xff0c;封装了以下接口的实现&#xff1a; ClosableResolver 接口实现TransportClientFactory 接口实现EurekaHttpClient 接口实现及其对应的 EurekaHttpClientFactory 接口实现 private …

Golang之路---01 Golang VS Code创建项目

Golang VS Code创建项目 代码组织 Golang使用包和模块来组织代码&#xff0c;包对应到文件系统就是文件夹&#xff0c;模块就是xxx.go的go源文件。一个包中会有多个模块&#xff0c;或者多个子包。 早期使用的是gopath来管理项目&#xff0c;不方便&#xff0c;比较麻烦&…

电子技术的发展

本资料仅用于学习和讨论如有侵权请反馈 1.1 第一台只能存储640M 什么是模拟信号: 2.1 把声波转化为电信号 2.2 微音器输出的某一段信号的波形 3、最简单有个蜂鸣器,再好一点有个喇叭 4、人说话的声音是个很复杂的声音 5、嵌入式实时操作系统: 6、结构到函数 6.1 学习环境…

深度学习,神经网络介绍

目录 1.神经网络的整体构架 2.神经网络架构细节 3.正则化与激活函数 4.神经网络过拟合解决方法 1.神经网络的整体构架 ConvNetJS demo: Classify toy 2D data 我们可以看看这个神经网络的网站&#xff0c;可以用来学习。 神经网络的整体构架如下1&#xff1a; 感知器&…

二叉树的前,中,后序的非递归实现(c++)

前言 对于二叉树来说&#xff0c;遍历它有多种方式&#xff0c;其中递归遍历是比较简单的&#xff0c;但是非递归的实现就有一定的难度&#xff0c;在这里介绍一种非递归实现二叉树遍历的方式。 1.前序遍历 1.1思路 其实对于二叉树的非递归实现&#xff0c;实际上就是用代码来…

Android HTTP使用(详细版)

前言 在面试过程中,HTTP 被提问的概率还是比较高的。 小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。 HTTP 基本概念 Get 与 Post HTTP 特性…

Linux系统使用(超详细,暑假弯道超车!!)

目录 Linux操作系统简介 Linux和windows区别 Linux常见命令 Linux目录结构 Linux命令提示符 常用命令 ls cd pwd touch cat echo mkdir rm cp mv vim vim的基本使用 grep netstat Linux面试题 Linux操作系统简介 Linux操作系统是和windows操作系统是并列的关系。只不过只…

GitHub上怎么寻找项目?

前言 下面由我精心整理的关于github项目资源搜索的一些方法&#xff0c;这些方法可以帮助你更快更精确的搜寻到你需要的符合你要求的项目。 写文章不易&#xff0c;如果这一篇问文章对你有帮助&#xff0c;求点赞求收藏~ 好&#xff0c;下面我们直接进入正题——> 首先我…

90%的测试工程师是这样使用Postman做接口测试的

一&#xff1a;接口测试前准备 接口测试是基于协议的功能黑盒测试&#xff0c;在进行接口测试之前&#xff0c;我们要了解接口的信息&#xff0c;然后才知道怎么来测试一个接口&#xff0c;如何完整的校验接口的响应值。 那么问题来了&#xff0c;那接口信息从哪里获取呢&…

选择排序算法

选择排序 算法说明与代码实现&#xff1a; 以下是使用Go语言实现的选择排序算法示例代码&#xff1a; package mainimport "fmt"func selectionSort(arr []int) {n : len(arr)for i : 0; i < n-1; i {minIndex : ifor j : i 1; j < n; j {if arr[j] < a…

杨辉三角,给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。

题记&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: …

Jenkins通过OpenSSH发布WinServer2016

上一篇文章> Jenkins集成SonarQube代码质量检测 一、实验环境 jenkins环境 jenkins入门与安装 容器为docker 主机IP系统版本jenkins10.10.10.10rhel7.5 二、OpenSSH安装 1、下载 官网地址&#xff1a;https://learn.microsoft.com/zh-cn/windows-server/administration/op…