element-ui Tree 树形控件 过滤保留子级并获取过滤后的数据 多选改单选

news2024/11/27 0:39:25

本示例基于vue2 + element-ui

element-ui 的官网demo是只保留到过滤值一级的,并不会保留其子级

目标

1、Tree 树形控件 保留过滤值的子级

2、在第一次过滤数据的基础上进行第二次过滤

3、Tree 树形控件 多选改为单选,且只有最末端子级可以选择

不足之处

过滤时无法指定过滤哪一级的数据(保留其子级数据)

实际场景需求

  1. 第一次过滤时只过滤第三级数据
  2. 第二次过滤时在第一次过滤的基础上过滤最后一级

1 暂时无法实现(如果有大佬用前端方法实现,记得call我!)

2 过滤最后一级可以实现(代码随后附上)

先看效果

1、2

3  多选改单选效果

Tree 树形控件 保留过滤值的子级

<el-tree
  class="filter-tree"
  node-key="id"
  :data="treeData"
  :props="defaultProps"
  default-expand-all
  show-checkbox
  @check-change="handleCheckChange"
  :filter-node-method="filterNode"
  ref="tree">
</el-tree>


// 对树节点进行筛选时执行的方法
filterNode (value, data, node) {
  let parentNode = node.parent; // 父级node
  let labels = [node.label]; // 当前node的名字
  let level = 1; // 层级
  while (level < node.level) {
    labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字
    parentNode = parentNode.parent;
    level++;
  }
  return labels.some((d) => d.indexOf(value) !== -1);
},

在第一次过滤数据的基础上进行第二次过滤

1、下载插件库

npm install -S circular-json

2、在使用页面引入

import CircularJSON from 'circular-json'

3、代码应用

<template>
  <div class="about-container">
    <h1>获取过滤后的tree数据</h1>
    <el-input
      clearable
      placeholder="第一次过滤"
      @keyup.enter.native="handleFilter1"
      v-model="firstText">
    </el-input>
    <el-input
      style="margin-top: 10px;"
      clearable
      placeholder="第二次过滤"
      @keyup.enter.native="handleFilter2"
      v-model="secondText">
    </el-input>
    <el-button @click="handleFilter1(),handleFilter2()" type="primary" icon="el-icon-search">搜索</el-button>
    <div>
      <el-tree
        class="filter-tree"
        node-key="id"
        :data="treeData"
        :props="defaultProps"
        default-expand-all
        show-checkbox
        @check-change="handleCheckChange"
        :filter-node-method="filterNode"
        ref="tree">
      </el-tree>
    </div>
  </div>
</template>

<script>
  // 在使用的组件内引入
  import CircularJSON from 'circular-json'

  export default {
    data() {
      return {
        // 第一次过滤
        firstText: '',
        // 第二次过滤
        secondText:'',
        // tree控件的渲染值
        treeData: [{
          id: 1,
          label: '一级1',
          children: [{
            id: 4,
            label: '二级1-1',
            children: [{
              id: 9,
              label: '三级1-1-1',
              children: [{
                id:91,
                label: '四级1'
              },{
                  id:92,
                  label: '四级2'
              }]
            }, {
              id: 10,
              label: '三级1-1-2'
            }]
          }]
        }, {
          id: 2,
          label: '一级2',
          children: [{
            id: 5,
            label: '二级2-1'
          }, {
            id: 6,
            label: '二级2-2'
          }]
        }, {
          id: 3,
          label: '一级',
          children: [{
            id: 7,
            label: '二级3-1'
          }, {
            id: 8,
            label: '二级3-2'
          },{
            id: 82,
            label: '四级3'
          }]
        },{
          id: 31,
          label: '奇迹',
          children: [{
            id: 71,
            label: '奇迹1'
          }, {
            id: 81,
            label: '奇迹2'
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        },
        // tree的原版备份数据
        deepCloneTreeData:[],
        // 第一次过滤后tree控件渲染数据
        firstFilterdata:[],
      }
    },
    mounted() {
      this.deepClone(this.treeData).then((res)=>{
        this.deepCloneTreeData = res;
      })
    },
    methods: {
      // 第一次过滤
      handleFilter1() {
        // 第一次过滤时没有输入值,即用tree控件的原始值
        if(!this.firstText){
          this.treeData = this.deepCloneTreeData;
          this.firstFilterdata = this.deepCloneTreeData;
          return
        }
        this.$refs.tree.filter(this.firstText)
        this.firstFilterdata = this.getFilterData();
      },
      // 第二次过滤
      handleFilter2() {
        // 基于第一次过滤出来的数据
        if(this.firstFilterdata.length > 0) this.treeData = this.firstFilterdata;
        this.$nextTick(()=>{
          this.$refs.tree.filter(this.secondText);
        })
      },
      // 对树节点进行筛选时执行的方法
      filterNode (value, data, node) {
        let parentNode = node.parent; // 父级node
        let labels = [node.label]; // 当前node的名字
        let level = 1; // 层级
        while (level < node.level) {
          labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字
          parentNode = parentNode.parent;
          level++;
        }
        return labels.some((d) => d.indexOf(value) !== -1);
      },
      // tree 的选择事件
      handleCheckChange(data, checked, indeterminate) {
        const arr = this.$refs.tree.getCheckedKeys()
      },
      // 需要获取过滤后的 Tree组件数据
      getFilterData() {
          const rootData = this.$refs.tree.root;
          if (rootData.visible) {
            const childNodesStr = CircularJSON.stringify(rootData.childNodes);
            const childNodes = CircularJSON.parse(childNodesStr);
            const filterData = this.recursionNodes(childNodes);
            return filterData;
        }
      },
      /**
       * 递归遍历数据
       * 这里解释一下为什么要用CircularJSON这个插件,因为element tree
       * node数据存在一个对象里的子项存在循环引用,存在循环引用的对象
       */
      recursionNodes(childNodes) {
        const nodes = childNodes;
        const result = [];
        for (const item of nodes) {
          if (item.visible) {
            result.push(item.data);
          }
          if (item.childNodes && item.childNodes.length) {
            const tempResult = this.recursionNodes(item.childNodes);
            item.data.children = tempResult;
          }
        }
        return result;
      },
      /**
       * 深拷贝
       */
      deepClone(obj){
          return new Promise((resolve) => {
              const { port1,port2 } = new MessageChannel();
              port1.postMessage(obj);
              port2.onmessage = (msg) => {
                  resolve(msg.data)
              }
          })
      }
    },
  }
</script>

只过滤最后一级

/** 
 * 数据处理
 * 
 * 需要对每级数据进行level标记,方便后续过滤
 */
treeData: [{
  id: 1,
  label: '一级1',
  level:1,
  children: [{
    id: 4,
    label: '二级1-1',
    level:2,
    children: [{
      id: 9,
      label: '三级1-1-1',
      level:3,
      children: [{
        id:91,
        label: '四级1',
        level:4,
      },{
          id:92,
          label: '四级2',
          level:4,
      }]
    }, {
      id: 10,
      label: '三级1-1-2',
      level:3,
    }]
  }]
}, {
  id: 2,
  label: '一级2',
  level:1,
  children: [{
    id: 5,
    label: '二级2-1',
    level:2,
  }, {
    id: 6,
    label: '二级2-2',
    level:2,
  }]
}, {
  id: 3,
  label: '一级',
  level:1,
  children: [{
    id: 7,
    label: '二级3-1',
    level:2,
  }, {
    id: 8,
    label: '二级3-2',
    level:2,
  },{
    id: 82,
    label: '四级3',
    level:2,
  }]
},{
  id: 31,
  label: '奇迹',
  level:1,
  children: [{
    id: 71,
    label: '奇迹1',
    level:2,
  }, {
    id: 81,
    label: '奇迹2',
    level:2,
  }]
}]


// 对树节点进行筛选时执行的方法
filterNode(value, data, node) {
  /**
   * 筛选最后一级可用
   * 
   * [4].includes(data.level
   * [] 中写入最后一级的level值
   */
  if ([4].includes(data.level) && data.label.indexOf(value) !== -1) {
    console.log(value,data,node,'4-------',data.label.indexOf(value));
    let parentNode = node.parent; // 父级node
    let labels = [node.label]; // 当前node的名字
    let level = 1; // 层级
    while (level < node.level) {
      // console.log(labels,'labels');
      labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字
      parentNode = parentNode.parent;
      level++;
    }
    return labels.some((d) => d.indexOf(value) !== -1);
  }
},

Element tree组件 多选改为单选

<el-tree
  class="treeRadio"
  check-strictly
  @check-change="deptCheck"

deptCheck(data, check, childCheck) {
  if(check){
    this.$refs.tree.setCheckedNodes([data]);
  }
}

// css 让父级不显示checkbox
::v-deep .el-tree .el-tree-node .is-leaf + .el-checkbox .el-checkbox__inner{
  display: inline-block;
}
::v-deep .el-tree .el-tree-node .el-checkbox .el-checkbox__inner{
  display: none;
}
::v-deep .treeRadio .el-checkbox__inner{
  border-radius: 50%;
  transform: scale(1.2);
}
// 样式改为单选框的样式
::v-deep .treeRadio .el-checkbox__inner{
  border-radius: 50%;
  transform: scale(1.2);
}

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

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

相关文章

「解析」Windows 如何优雅使用 Terminal

所谓工欲善其事必先利其器&#xff0c;对于开发人员 Linux可能是首选&#xff0c;但是在家学习的时候&#xff0c;我还是更喜欢使用 Windows系统&#xff0c;首先是稳定&#xff0c;其次是习惯了。当然了&#xff0c;我还有一台专门安装 Linux系统的小主机用于学习Linux使用&am…

八、QLayout 用户基本资料修改(Qt5 GUI系列)

目录 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 在很多应用程序中会有用户注册或用户编辑信息等界面。本文就设计一个用户信息编辑界面。要求包含用户名、姓名、性别、部门、年龄、头像、个人说明等信息。 二、实现代码 #ifndef DIALOG_H #define D…

MySQL数据管理(一)

一、列类型 列类型指规定数据库中该列存放的数据类型 列类型分类 数值类型字符串类型日期和时间型数值类型 数值类型 字符串类型 日期和时间类型 MySQL允许“不严格”语法&#xff0c;任何标点符号都可以作为日期部分之间的间隔符&#xff0c;如“24-01-03”、“24.01.03”…

第二百四十五

我们在上一章回中介绍了"修改页面导航中遇到的问题"沉浸式状态样相关的内容&#xff0c;本章回中将介绍如何修改Avatar的大小.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在正常使用CirCleAvatar组件时可以通过该组件的radius属性来修改它的…

Git 对项目更新的时候提示错误 repository not owned by current user

遇到 Git 提示的错误信息为&#xff1a;repository not owned by current user 上图显示的是错误的信息。 问题和解决 出现上面错误信息的原因是当前文件夹的权限和 Git 的执行权限不一直导致的。 我们的问题是我们希望在网盘上使用 Git 更新克隆后的代码&#xff0c;但登录…

KeyError: ‘model_state_dict‘

问题 加载模型权重文件时获取model_state_dict键失败 解决 单步调试发现保存模型权重时正确保存了该键值对&#xff0c;再次调试时发现莫名奇妙又没错了 首先确认保存模型时的状态字典键名&#xff1a;确保在保存模型权重时&#xff0c;正确地使用了 model.state_dict() 方法…

机器学习原理到Python代码实现之LinearRegression

Linear Regression 线性回归模型 该文章作为机器学习的第一篇文章&#xff0c;主要介绍线性回归模型的原理和实现方法。 更多相关工作请参考&#xff1a;Github 算法介绍 线性回归模型是一种常见的机器学习模型&#xff0c;用于预测一个连续的目标变量&#xff08;也称为响应变…

el-autocomplete远程搜索使用及el-upload上传多个文件流给后端,详情接口返回的是文件地址,前端将文件地址转成文件流,回传文件流给后端

最近遇到一个项目,里面有2个需求我觉得挺常见的,第一个需求是一个表单里,当用户在输入名称后,前端调接口发请求获取到关联名称的企业名称,并展示,然后当用户选中企业后,前端调接口获取选中企业的具体信息,并填充到表单里;第二个需求是,表单里有个上传图片的功能,前端…

【elfboard linux开发板】8. watchdog 和 mpu

1. 用文件IO的方式使用watchdog a. ioctl 命令说明 需要的头文件#include <sys/ioctl.h> 格式&#xff1a;int ioctl(int fd, unsigned long request, …) fd 必须被打开 第二个参数是一个依赖设备的请求代码 第三个参数是一个无类型的内存指针 返回值&#xff1a;成功为…

Python 资源大全中文版

文末有链接 资源列表 环境管理 管理 Python 版本和环境的工具 p&#xff1a;非常简单的交互式 Python 版本管理工具。 pyenv&#xff1a;简单的 Python 版本管理工具。 Vex&#xff1a;可以在虚拟环境中执行命令。 virtualenv&#xff1a;创建独立 Python 环境的工具。 …

【React系列】react-router

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 认识react-router 1.2. 前端路由原理 前端路由是如何做到URL和内容进行映射呢&#xff1f;监听URL的改变。 UR…

Halcon粘连木材图像的目标分割计数

Halcon粘连木材图像的目标分割计数 文章目录 Halcon粘连木材图像的目标分割计数1. 提取面积较小区域2. 分割较大区域3. 区域合并与计数 本文以一个实际场景图片为例&#xff0c;介绍阈值处理与形态学计算的应用。案例图像如图所示,图&#xff08;a&#xff09;为输入的原始图像…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -小程序端TabBar搭建

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

突破技术边界:R与jsonlite库探秘www.snapchat.com的数据之旅

概述 Snapchat是一款流行的社交媒体应用&#xff0c;它允许用户发送和接收带有滤镜和贴纸的照片和视频&#xff0c;以及创建和观看故事和发现内容。Snapchat的数据是非常有价值的&#xff0c;因为它可以反映用户的行为、偏好和趋势。然而&#xff0c;Snapchat的数据并不容易获…

从0开始python学习-40.通过正则表达式/json进行接口关联

目录 1. 正则表达式&#xff1a;使用re库&#xff08;需安装-pip install re&#xff09;&#xff0c;只能提取字符串的数据。 1.1 re.seach&#xff1a;提取一个值&#xff0c;得到的是一个对象&#xff0c;通过下标group(1)取值&#xff0c;如果没有匹配到值则返回None 1.…

优化企业运营,深入探索SAP库存管理解决方案

SAP库存管理是SAP提供的一款领先的企业库存管理解决方案。它致力于帮助企业实现对库存的全面掌控&#xff0c;优化供应链管理&#xff0c;降低库存成本&#xff0c;提高客户满意度。这个功能强大的系统为企业提供了丰富的仓储管理功能&#xff0c;如库存盘点、物料追踪、供应商…

WPF DatePicker与Calendar的使用和样式修改

什么是DatePicker&#xff0c;Calendar Calendar&#xff1a;日历&#xff08;显示年月日视图控件&#xff09;DatePicker&#xff1a;日期选择器&#xff08;是一个更小的控件&#xff0c;点击控件时才会弹出一个日历&#xff09; Calendar使用 常用属性 DisplayMode&#…

MacOS - 苹果电脑程序还能正常启动,但图标消失不见了~

问题描述 网上有一些解决方案说是 killall Finder 命令&#xff0c;重置 Docker 等等&#xff0c;但是发现还是不行&#xff0c;于是必杀技…… 解决方案 方案一、删除该 App&#xff0c;重装即可方案二、如果懒得重装&#xff0c;可以在 Finder 中找到对应的应用程序&#xf…

FPGA高端项目:纯verilog的 10G-UDP 高速协议栈,提供7套工程源码和技术支持

目录 1、前言免责声明更新说明 2、相关方案推荐我这里已有的以太网方案本协议栈的千兆网UDP版本1G 千兆网 TCP-->服务器 方案1G 千兆网 TCP-->客户端 方案10G 万兆网 TCP-->服务器客户端 方案 3、该UDP协议栈性能4、详细设计方案设计架构框图网络调试助手GT资源使用GT…

1.3 金融数据可视化

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1.1 编程基础   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas 1.2 金融数据处理 1.3 金融数据可视化 文章目录 1. 金融数据可视化1.1. matplotlib1.1.1. 沪深300走势图1.1.2. 日线均线…