实现 select 中嵌套 tree 外加搜索

实现 select 中嵌套 tree 外加搜索

参考地址实现地址
在这里插入图片描述

代码

<el-form-item label="考核人员" prop="userIdArr" v-if="title == '发起考核'">
  <el-popover v-model="popoverVisible" placement="bottom" trigger="click" ref="popover">
     // click:点击select时弹出框显示
     // popover+tree用于选择,树形控件放在弹出框中
    <el-input class="input" placeholder="此处键入'关键词'搜索查询" prefix-icon="el-icon-search" v-model="treeFilter"
      size="mini" v-focus clearable />
    <!-- 通过 checkbox 进行选择,通过 checkChange 来进行保存值 -->
    <el-tree :data="deptOptions" :props="defaultProps" show-checkbox @check="checkChange"
      :default-checked-keys="this.form.userIdArr" ref="tree" node-key="iid" :filter-node-method="filterNode"
      :default-expand-all="false" :style="`max-height: ${treeMaxHeight}px; overflow-y: auto;`" />
    // select展示选择结果,储存选择值typeValue
    <el-select slot="reference" multiple collapse-tags v-model="form.userIdArr" placeholder="请选择"
      popper-class="hiddenSel" clearable @clear="clearTag" @remove-tag="removeTag">
      <el-option v-for="item in typeOption" :key="item.iid" :label="item.label" :value="item.iid" />
    </el-select>
  </el-popover>
</el-form-item>

data 数据

// 需把数据整理成以下结构
// tree数据(children的id第一位为父级id,用于在select中清除某一点,可找到其父级去掉全选)
deptOptions: [], // tree 的数据
typeOption: [], // select 选择框一维数据
defaultProps: {
  // tree 的显示类名
  children: "children",
  label: "label",
},
treeFilter: "", // 搜索框绑定值,用作过滤
// 选中数组
  ids: [],

methods 方法:

watch: {
  // 搜索过滤,监听input搜索框绑定的treeFilter
  treeFilter(val) {
    this.$refs.tree.filter(val);
    // 当搜索框键入值改变时,将该值作为入参执行树形控件的过滤事件filterNode
  },
}
methods: {
// 发起考核
 // select 框部分
 /** 查询部门下拉树结构 */
 getDeptTree() {
   userTreeList().then((response) => {
     // 将数据 user 添加进 children,并且将字段名更改下
     this.deptOptions = this.copyAndRenameFieldsInArray(response.data);

     // 对数据进行添加 iid
     this.deptOptions = this.addIid(this.deptOptions);

     // 处理好的数据 进行扁平化
     this.typeOption = this.flattenData(this.deptOptions);
   });
 },
 // 将部门tree进行扁平化
 flattenData(data) {
   const result = [];

   function flatten(item) {
     result.push({ id: item.id, label: item.label, iid: item.iid });

     if (item.children) {
       item.children.forEach((child) => {
         flatten(child);
       });
     }
   }

   data.forEach((item) => {
     flatten(item);
   });

   return result;
 },
 // 将 user 添加进 children
 copyAndRenameFieldsInArray(data) {
   data.forEach((node) => {
     if (node.users && node.users.length > 0) {
       node.children = node.children || [];
       // 将复制并重命名字段的数据拼接到 children 数组的最前面
       node.children.unshift(
         ...node.users.map((user) => ({
           userId: user.userId,
           id: user.userId,
           userName: user.userName,
           label: user.nickName,
           deptId: user.deptId,
           nickName: user.nickName,
         }))
       );
       node.users = [];
     }

     if (node.children && node.children.length > 0) {
       this.copyAndRenameFieldsInArray(node.children);
     }
   });
   return data;
 },
 // 加字段 iid
 addIid(data, iidPrefix = "") {
   return data.map((item) => {
     const iid = iidPrefix + item.id;
     const newItem = { ...item, iid };

     if (item.children) {
       newItem.children = this.addIid(item.children, iid + "-");
     }

     return newItem;
   });
 },
 // tree选择值修改时
 checkChange() {
   this.form.userIdArr = [];
   // 将tree选择的id赋值给select
   this.$refs["tree"]?.getCheckedNodes(true).forEach((value) => {
     // 父级在select中不展示
     if (value.iid.indexOf("-") > 0) {
       this.form.userIdArr.push(value.iid);
     }
   });
 },
 // 模糊查询(搜索过滤),实质为筛选出树形控件中符合输入条件的选项,过滤掉其他选项
 filterNode(value, data) {
   if (!value) return true;
   let filterRes =
     data.label.toLowerCase().indexOf(value.toLowerCase()) !== -1;
   return filterRes;
 },
 // 清空select
 clearTag() {
   // 清空tree选择
   this.$refs["tree"].setCheckedKeys([]);
 },
 // 从select中单个移除时,保持tree选择值同步移除
 removeTag(data) {
   // 获取tree目前选择的值
   var chooseData = this.$refs["tree"].getCheckedKeys(true);
   var deleteIndex = "";
   // 找到chooseData中与清除的data相同的值
   chooseData.forEach((value, index) => {
     if (value === data) {
       deleteIndex = index;
     }
   });
   // 从tree目前选择值中去掉
   chooseData.splice(deleteIndex, 1);
   // 若有全选情况,tree的选择值中有父级id,而select中无父级id,需用children的id找到父级id并去掉
   // 查找其父级id是否在chooseData中(即原来此父级是否全选),若在则去掉
   var findFatherData = chooseData.find(
     (element) => element === data.split("-")[0]
   );
   if (findFatherData) {
     chooseData.splice(chooseData.indexOf(findFatherData), 1);
   }
   // 将修改后的值再赋给tree
   this.$refs["tree"].setCheckedKeys(chooseData);
 },
 // 时间戳转化为时间
 formatDate(dateString) {
   const date = new Date(dateString);

   const year = date.getFullYear();
   const month = ("0" + (date.getMonth() + 1)).slice(-2);
   const day = ("0" + date.getDate()).slice(-2);
   const hours = ("0" + date.getHours()).slice(-2);
   const minutes = ("0" + date.getMinutes()).slice(-2);
   const seconds = ("0" + date.getSeconds()).slice(-2);

   const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;

   return formattedDate;
 },
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL-单行函数:数值函数、字符串函数、日期和时间函数、流程控制函数、加密与解密函数、MySQL信息函数、其他函数、单行函数练习

1.数值函数 1.1 基本的操作 SELECT ABS(-123),ABS(32),SIGN(-23),SIGN(43),PI(),CEIL(32.32),CEILING(-43.23),FLOOR(32.32), FLOOR(-43.23),MOD(12,5),12 MOD 5,12 % 5 FROM DUAL;1.2 取随机数 SELECT RAND(),RAND(),RAND(10),RAND(10),RAND(-1),RAND(-1) FROM DUAL;1.3 四…

见证历史:Quantinuum与微软取得突破性进展,开启了可靠量子计算的新时代!

Quantinuum与微软的合作取得了重大突破&#xff0c;将可靠量子计算带入了新的时代。他们结合了Quantinuum的System Model H2量子计算机和微软创新的量子比特虚拟化系统&#xff0c;在逻辑量子比特领域取得了800倍于物理电路错误率的突破。这一创新不仅影响深远&#xff0c;加速…

Spring Boot 整合 RabbitMQ 实现延迟消息

关于 RabbitMQ 消息队列&#xff08;Message Queuing&#xff0c;简写为 MQ&#xff09;最初是为了解决金融行业的特定业务需求而产生的。慢慢的&#xff0c;MQ 被应用到了更多的领域&#xff0c;然而商业 MQ 高昂的价格让很多初创公司望而却步&#xff0c;于是 AMQP&#xff0…

点亮创意:ChatGPT如何搭桥DALL-E图像编辑新纪元

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

金融中的数学知识

随机偏微分方程相比普通偏微分方程具有额外的随机项&#xff0c;反映了其描述的现象具有随机性质

在ArcGIS Pro中优雅的制作荧光图

最近在网上看到了荧光图&#xff0c;觉得挺帅气&#xff0c;去网上查询了怎么制作荧光图&#xff0c;发现大部分都是QGIS的教程&#xff0c;作为ArcGIS的死忠用户&#xff0c;决定在ArcGIS Pro中实现&#xff0c;其实挺简单的。 1、软件&#xff1a;ArcGIS Pro3.0 2、点数据&a…

Linux的软链接和硬链接

1、软链接 概念&#xff1a;给文件创建一个快捷方式&#xff0c;依赖原文件&#xff0c;和普通文件没有区别。 特性&#xff1a; 可以给存在的文件或目录创建软链接可以给不存在的文件或目录创建软链接可以跨文件系统创建软链接删除软链接不影响原文件、删除原文件会导致软链…

【Java基础】Java基础知识整合

文章目录 1. 转义字符2. 变量2.1 字符串与整型相加2.2 byte和short的区别2.3 float和double的区别2.4 char类型2.5 boolean类型2.6 自动类型转换及运算2.7 强制类型转换2.8 String的转换2.9 除法运算2.10 取模规则 3. 自增4. 逻辑运算符5. 赋值运算 6. 三元运算符&#xff1a;7…

一文介绍回归和分类的本质区别 !!

文章目录 前言 1、回归和分类的本质 &#xff08;1&#xff09;回归&#xff08;Regression&#xff09;的本质 &#xff08;2&#xff09;分类&#xff08;Classification&#xff09;的本质 2、回归和分类的原理 &#xff08;1&#xff09;回归&#xff08;Regression&#x…

力扣 115. 不同的子序列

题目来源&#xff1a;https://leetcode.cn/problems/distinct-subsequences/description/ C题解&#xff1a;动态规划。 dp[i][j] 表示 t[0] ~ t[i-1] 在 s[0] ~ s[j-1] 中出现的个数。因为 t 短&#xff0c;所以把 t 放在外循环。 当 t[i-1] 不等于 s[j-1] 时&#xff0c;s[…

认识 Redis 与 分布式

Redis 官网页面 Redis官网链接 Redis 的简介 Redis 是一个在内存中存储数据的中间件 一方面用于作为数据库&#xff0c;另一方面用于作为数据缓存&#xff0c;适用于分布式系统中 Redis 基于网络&#xff0c;进行进程间通信&#xff0c;把自己内存中的变量给别的进程&#xf…

深度解析GPT中的Tokenizer

继学习完深度解析大语言模型中的词向量后&#xff0c;让我们继续学习大语言模型中另外几个重要概念&#xff1a;token&#xff08;词元&#xff09;、tokenization&#xff08;词元化&#xff09;、tokenizer&#xff08;词元生成器&#xff09;。 在GPT模型中&#xff0c;toke…

【与C++的邂逅之旅】--- 内联函数 auto关键字 基于范围的for循环 nullptr

关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა 博主专栏&#xff1a; &#x1f4a1; 与C的邂逅之旅 &#x1f4a1; 数据结构之旅 上篇我们了解了函数重载和引用&#xff0c;我们继续学习有关C的一些小语法— 内联函数&#xff0c;auto关键字&#xff0c;基于范围的for循环以及 nullptr&…

设计模式——建造者模式03

工厂模式注重直接生产一个对象&#xff0c;而建造者模式 注重一个复杂对象是如何组成的&#xff08;过程&#xff09;&#xff0c;在生产每个组件时&#xff0c;满足单一原则&#xff0c;实现了业务拆分。 设计模式&#xff0c;一定要敲代码理解 组件抽象 public interface …

02---webpack基础用法

01 entry打包的入口文件&#xff1a; 单入口entry是一个字符串:适用于单页面项目module.exports {entry:./src/index.js}多入口entry是一个对象module.exports {entry:{index:./src/index.js,app:./src/app.js}} 02 output打包的出口文件&#xff1a; 单入口配置module.ex…

【opencv】教程代码 —video(3) 视频背景剔除

bg_sub.cpp 这段代码的功能是把视频中的背景和前景分离&#xff0c;提取出前景的运动物体。根据用户选择的不同的模式&#xff0c;可以选择基于MOG2或者基于KNN的方法来进行背景减除。在处理每一帧图像的过程中&#xff0c;首先使用背景减除模型对图像帧进行处理&#xff0c;得…

RabbitMQ3.7.8集群分区(脑裂现象)模拟及恢复处置全场景测试

测试环境准备: MQ服务器集群地址&#xff0c;版本号为3.7.8&#xff1a; 管理控制台地址:http://173.101.4.6:15672/#/queues 集群状态 rabbitmqctl cluster_status 集群操作相关命令: 创建一个RabbitMQ集群涉及到如下步骤&#xff1a; 安装RabbitMQ&#xff1a; 在每台要在集…

JVM专题——类文件加载

本文部分内容节选自Java Guide和《深入理解Java虚拟机》, Java Guide地址: https://javaguide.cn/java/jvm/class-loading-process.html &#x1f680; 基础&#xff08;上&#xff09; → &#x1f680; 基础&#xff08;中&#xff09; → &#x1f680;基础&#xff08;下&a…

利用AI结合无极低码(免费版)快速实现接口开发教程,会sql即可,不需要编写编译代码

无极低码无代码写服务+AI实践 本次演示最简单的单表无代码增删改查发布服务功能,更复杂的多表操作,安全验证,多接口调用,自自动生成接口服务,生成二开代码,生成调用接口测试,一键生成管理界面多条件检索、修改、删除、查看、通用公共接口调用、通用无限级字典调用等后续…

【Linux】Ubuntu 文件权限管理

Linux 系统对文件的权限有着严格的控制&#xff0c;用于如果相对某个文件执行某种操作&#xff0c;必须具有对应的权限方可执行成功&#xff0c;这也是Linux有别于Windows的机制&#xff0c;也是基于这个权限机制&#xff0c;Linux可以有效防止病毒自我运行。因为运行的条件是必…