当前位置: 首页 > news >正文

实现 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搜索框绑定的treeFiltertreeFilter(val) {this.$refs.tree.filter(val);// 当搜索框键入值改变时,将该值作为入参执行树形控件的过滤事件filterNode},
}
methods: {
// 发起考核// select 框部分/** 查询部门下拉树结构 */getDeptTree() {userTreeList().then((response) => {// 将数据 user 添加进 children,并且将字段名更改下this.deptOptions = this.copyAndRenameFieldsInArray(response.data);// 对数据进行添加 iidthis.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 添加进 childrencopyAndRenameFieldsInArray(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;},// 加字段 iidaddIid(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赋值给selectthis.$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;},// 清空selectclearTag() {// 清空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);}// 将修改后的值再赋给treethis.$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;},
}

相关文章:

  • ROS 2边学边练(12)-- 创建一个工作空间
  • 提高空调压缩机能效的通用方法
  • 957: 逆置单链表
  • php获取拼多多详情api接口、商品主图
  • 算法基本概念
  • 6000000IOPS!FASS×kunpeng920全新突破
  • 小林coding图解计算机网络|基础篇01|TCP/IP网络模型有哪几层?
  • 【面试八股总结】超文本传输协议HTTP(二)
  • cesium键盘控制相机位置和姿态
  • 如何评估基于指令微调的视觉语言模型的各项能力-MMBench论文解读
  • 设计模式:外观模式
  • LeetCode | 数组 | 双指针法 | 27. 移除元素【C++】
  • windows安装Openssl
  • 力扣刷题部分笔记
  • vue3表单参数校验+正则表达式
  • ES6指北【2】—— 箭头函数
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [笔记] php常见简单功能及函数
  • [译]Python中的类属性与实例属性的区别
  • [译]如何构建服务器端web组件,为何要构建?
  • httpie使用详解
  • Mybatis初体验
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 前端之Sass/Scss实战笔记
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 算法系列——算法入门之递归分而治之思想的实现
  • 微信开源mars源码分析1—上层samples分析
  • 学习Vue.js的五个小例子
  • 用 Swift 编写面向协议的视图
  • 智能合约Solidity教程-事件和日志(一)
  • (2)Java 简介
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • *Django中的Ajax 纯js的书写样式1
  • .gitignore文件---让git自动忽略指定文件
  • .java 9 找不到符号_java找不到符号
  • .NET Framework 4.6.2改进了WPF和安全性
  • .net 受管制代码
  • /dev/sda2 is mounted; will not make a filesystem here!
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ C++ ] STL---string类的模拟实现
  • [C++] sqlite3_get_table 的使用
  • [Gamma]阶段测试报告
  • [HAOI2016]食物链
  • [Notice] 朋友们,blog更新http://jiang-hongfei.spaces.live.com
  • [Oh My C++ Diary]善用三目运算符(a?b:c)
  • [R] data.frame() creates list?
  • [selenium] Handling Untrusted SSL certificate error in firefox
  • [Vue 配置] Vite + Vue3 项目配置和使用 NProgress
  • [webpack] devtool里的7种SourceMap[转]