【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能 树结构 封装为组件使用

news2024/11/27 18:36:36

【组件】前端ElementUi 下拉Tree树形组件 带模糊搜索自动展开高亮功能 树结构

【组件】前端ElementUi 下拉Tree树形组件 带模糊

https://live.csdn.net/v/436057

单独使用

<template>
  <div>
    <el-popover
      style="overflow-y: auto; "
      placement="bottom"
      trigger="click">
      <el-input
        style="margin-bottom: 10px"
        v-model="搜索内容"
        clearable
        @clear="searchHandleIptClear"
      >
        <el-button slot="append" icon="el-icon-search" @click="search" size="small" >搜索</el-button>
      </el-input>
<!--      树结构-->
      <el-tree
        style="width:auto"
        ref="tree"
        :props="props"
        :data="data"
        :check-strictly="false"
        @check-change="handleCheckChange"
        show-checkbox
        node-key="id"
        :default-expanded-keys="需要展开的节点keys"
        :default-checked-keys="[]"
        @node-click="handleNodeClick"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
<!--          高亮的部分-->
          <span v-if="需要高亮节点数组.indexOf(data.id) !== -1" style="background-color: yellow">{{ node.label }}</span>
<!--          不需要高亮的部分-->
          <span v-else>{{ node.label }}</span>
        </span>
      </el-tree>
<!--      输入框 用来显示选中的节点内容-->
      <el-input slot="reference"
                style="width:380px"
                v-model="value.label"
                placeholder="节点"
                clearable
                readonly
                @clear="handleIptClear">
      </el-input>
    </el-popover>
  </div>
</template>
<script>
export default {
  data() {
    return {
      data: [{
        id: 1,
        label: '一级 1 A',
        children: [{
          id: 4,
          label: '二级 1-1 张三B',
          children: [{
            id: 9,
            label: '三级 1-1-1 李四C'
          }, {
            id: 10,
            label: '三级 1-1-2 王五a'
          }]
        }]
      }, {
        id: 2,
        label: '一级 2 赵六c',
        children: [{
          id: 5,
          label: '二级 2-1 张三b'
        }, {
          id: 6,
          label: '二级 2-2 李四a'
        }]
      }, {
        id: 3,
        label: '一级 3 王五D',
        children: [{
          id: 7,
          label: '二级 3-1 赵六d'
        }, {
          id: 8,
          label: '二级 3-2 钱七a'
        }]
      }],
      props: {
        label: 'label',
        children: 'children'
      },
      count: 1,
      value:{id:'', label: ''},
      需要高亮节点数组:[],
      需要展开的节点keys:[],
      搜索内容:''
    };
  },
  methods: {
    searchHandleIptClear(){
      this.需要高亮节点数组 = []
    },
    高亮模糊查询的节点递归(arr, 父节点){
      if(!arr || arr.length <= 0){
        return
      }
      let that = this
      arr.forEach(item=>{
        //不区分大小写匹配
        if(item.label.toUpperCase().indexOf(that.搜索内容.toUpperCase()) !== -1){
          console.log('搜索内容匹配', that.搜索内容, item, 父节点)
          that.需要高亮节点数组.push(item.id);
          if(父节点){
            that.需要展开的节点keys.push(父节点.id)
          }
        }
        if(item.children){
          that.高亮模糊查询的节点递归(item.children, item)
        }
      })
    },
    /**
     * 点击搜索
     */
    search(){
      let that = this
      //1 过滤所有内容
      that.需要高亮节点数组 = []
      that.需要展开的节点keys = []
      if(that.搜索内容){
        this.高亮模糊查询的节点递归(this.data, null)
      }
      //3 展开匹配到的节点内容
    },
    // 清空输入框内容
    handleIptClear(){
      console.log('清空输入框内容')
      //清空选中内容
      this.$refs.tree.setCheckedNodes([])
      this.value.id = ''
      this.value.label = ''
    },
    /**
     * 更新被选中的值
     */
    updateCheck(){
      const seltedNodes = this.$refs.tree.getCheckedNodes()
      console.log(seltedNodes)
      const ids = seltedNodes.map(n => n.id)
      const labels = seltedNodes.map(n => n.label)
      this.value.id = ids + ''
      this.value.label = labels + ''
    },
    // checkbox被选中或取消选中
    handleCheckChange(arg1, arg2, arg3){
      console.log(arg1, arg2, arg3);
      this.updateCheck()
    },
    // 节点被点击
    handleNodeClick(arg1, arg2, arg3){
      console.log('nodes:', arg1, arg2, arg3)
      this.updateCheck()
    },
  }
};
</script>

封装为组件使用方法

引用方法

<template>
  <div>
<!--    树结构组件-->
    <TreeSelector
      ref="TreeSelectorRef"
      :treeData="treeData"
      搜索按钮名称="搜索"
      提示词placeholder="请点击选择"
      :是否区分大小写="false"
      高亮样式Style="background-color: yellow"
    >
    </TreeSelector>
    <el-button @click="buttonClick">设置需要高亮的节点1</el-button>
    <el-button @click="buttonClick2">设置需要高亮的节点2</el-button>
    <el-button @click="getCheckedKeys">获取选中节点的keys</el-button>
    <el-button @click="getCheckedNodes">获取选中节点的数据</el-button>
    <el-button @click="setCheckedKeys">设置选中节点</el-button>
    <el-button @click="appendSetCheckedKeys">追加设置选中节点</el-button>
  </div>
</template>
<script>
//引用组件
import TreeSelector from '@/components/下拉框/下拉树组件.vue'

export default {
  components:{
    TreeSelector
  },
  data() {
    return {
      treeData: [{
        id: 1,
        label: '一级 1 A',
        children: [{
          id: 4,
          label: '二级 1-1 张三B',
          children: [{
            id: 9,
            label: '三级 1-1-1 李四C'
          }, {
            id: 10,
            label: '三级 1-1-2 王五a'
          }]
        }]
      }, {
        id: 2,
        label: '一级 2 赵六c',
        children: [{
          id: 5,
          label: '二级 2-1 张三b'
        }, {
          id: 6,
          label: '二级 2-2 李四a'
        }]
      }, {
        id: 3,
        label: '一级 3 王五D',
        children: [{
          id: 7,
          label: '二级 3-1 赵六d'
        }, {
          id: 8,
          label: '二级 3-2 钱七a'
        }]
      }],
    };
  },
  methods: {
    buttonClick(){
      this.$refs.TreeSelectorRef.需要高亮节点数组 = [1, 2]
    },
    buttonClick2(){
      this.$refs.TreeSelectorRef.需要高亮节点数组 = [3]
    },
    /**
     * 获取选中的节点数据
     */
    getCheckedNodes(){
      let 已选中的节点数据 = this.$refs.TreeSelectorRef.getCheckedNodes()
      console.log(已选中的节点数据)
    },
    /**
     * 获取选中的节点keys数据
     */
    getCheckedKeys(){
      let 已选中的节点keys = this.$refs.TreeSelectorRef.getCheckedKeys()
      console.log(已选中的节点keys)
    },
    setCheckedKeys(){
      let checkArr = [1, 2]
      this.$refs.TreeSelectorRef.setCheckedKeys(checkArr)
    },
    /**
     * 追加设置选中的节点
     */
    appendSetCheckedKeys(){
      let checkArr = [1]
      this.$refs.TreeSelectorRef.appendSetCheckedKeys(checkArr)
    }
  }
};
</script>

封装为组件

<template>
  <div>
    <!-- 使用 Element UI 的 Popover 组件实现下拉框 -->
    <el-popover
      style="overflow-y: auto; "
      placement="bottom"
      trigger="click">
      <!-- 输入框用于搜索树结构中的节点 -->
      <el-input
        style="margin-bottom: 10px"
        v-model="searchContent"
        clearable
        @clear="searchHandleIptClear"
      >
        <el-button slot="append" icon="el-icon-search" @click="search" size="small" >{{搜索按钮名称}}</el-button>
      </el-input>
      <!-- 树结构展示数据 -->
      <el-tree
        style="width:auto"
        ref="tree"
        :props="props"
        :data="treeData"
        :check-strictly="false"
        @check-change="handleCheckChange"
        show-checkbox
        node-key="id"
        :default-expanded-keys="需要展开的节点keys"
        @node-click="handleNodeClick"
      >

        <span class="custom-tree-node" slot-scope="{ node, data }">
<!--          高亮的部分-->
          <span v-if="需要高亮节点数组 && 需要高亮节点数组.indexOf(data.id) !== -1" :style="高亮样式Style">{{ node.label }}</span>
<!--          不需要高亮的部分-->
          <span v-else>{{ node.label }}</span>
        </span>
      </el-tree>
<!--      输入框 用来显示选中的节点内容-->
      <el-input slot="reference"
                style="width:380px"
                v-model="value.label"
                :placeholder="提示词placeholder"
                clearable
                readonly
                @clear="handleIptClear">
<!--        清除按钮-->
        <i
          slot="suffix"
          @click="IptClearClick"
          style="margin-top: 11px; cursor: pointer"
          class="el-icon-circle-close clear-button"></i>
      </el-input>
    </el-popover>
  </div>
</template>
<script>
export default {
  name: 'TreeSelector', // 组件名称
  /**
   * 属性
   */
  props: {
    // 树结构的数据源
    treeData: {
      type:Array,
      required:true,
      default:()=>[]
    },
    高亮样式Style: {
      type:String,
      default:()=>'background-color: yellow'
    },
    是否区分大小写: {
      type:Boolean,
      default:()=>false
    },
    //搜索按钮名称
    搜索按钮名称:{
      type:String,
      default:()=>'搜索'
    },
    //提示词placeholder
    提示词placeholder:{
      type:String,
      default:()=>'点击选择'
    },
  },
  data() {
    return {
      需要高亮节点数组:[],
      // 已选中的节点keys:[],
      需要展开的节点keys:[],
      searchContent:'',
      props: {
        label: 'label',
        children: 'children'
      },
      value:{id:'', label: ''},
    };
  },
  mounted() {
  },
  methods: {
    //清空搜索框内容事件
    searchHandleIptClear(){
      this.需要高亮节点数组 = []
    },
    高亮模糊查询的节点递归(arr, 父节点){
      if(!arr || arr.length <= 0){
        return
      }
      let that = this
      arr.forEach(item=>{
        let labelTmp = item.label;
        let searchContentTmp = that.searchContent;
        //不区分大小写匹配
        if(that.是否区分大小写 === false){
          labelTmp = labelTmp.toUpperCase()
          searchContentTmp = searchContentTmp.toUpperCase()
        }

        if(labelTmp.indexOf(searchContentTmp) !== -1){
          // console.log('搜索内容匹配', that.searchContent, item, 父节点)
          that.需要高亮节点数组.push(item.id);
          if(父节点){
            that.需要展开的节点keys.push(父节点.id)
          }
        }
        if(item.children){
          that.高亮模糊查询的节点递归(item.children, item)
        }
      })
    },
    /**
     * 点击搜索
     */
    search(){
      let that = this
      //1 过滤所有内容
      that.需要高亮节点数组 = []
      that.需要展开的节点keys = []
      if(that.searchContent){
        this.高亮模糊查询的节点递归(this.treeData, null)
      }
    },
    IptClearClick(event){
      // console.log(event)
      // event.preventDefault();
      this.handleIptClear()
    },
    // 清空输入框内容
    handleIptClear(){
      // console.log('清空输入框内容')
      //清空选中内容
      this.$refs.tree.setCheckedNodes([])
      this.value.id = ''
      this.value.label = ''
    },
    /**
     * 更新被选中的值
     */
    updateCheck(){
      const seltedNodes = this.getCheckedNodes()
      // console.log(seltedNodes)
      const ids = seltedNodes.map(n => n.id)
      const labels = seltedNodes.map(n => n.label)
      this.value.id = ids + ''
      this.value.label = labels + ''
    },
    // checkbox被选中或取消选中
    handleCheckChange(arg1, arg2, arg3){
      // console.log(arg1, arg2, arg3);
      this.updateCheck()
    },
    // 节点被点击
    handleNodeClick(arg1, arg2, arg3){
      // console.log('nodes:', arg1, arg2, arg3)
      this.updateCheck()
    },
    /**
     * 获取已选中的节点集合
     */
    getCheckedNodes(){
      return this.getTreeRef().getCheckedNodes();
    },
    /**
     * 获取已选中的节点keys集合
     */
    getCheckedKeys(){
      return this.getCheckedNodes().map(n => n.id);
    },
    /**
     * 追加设置选中的节点
     * @param arr
     */
    appendSetCheckedKeys(arr){
      let 已选中的keys = this.getCheckedKeys()
      const mergedArray = [...已选中的keys, ...arr];
      const mergedSet = new Set(mergedArray);
      this.setCheckedKeys(Array.from(mergedSet))
    },
    /**
     * 设置选中的节点
     * @param arr
     */
    setCheckedKeys(arr){
      this.getTreeRef().setCheckedKeys(arr)
    },
    /**
     * 获取tree ref
     * https://element.eleme.cn/#/zh-CN/component/tree
     * @returns {HTMLElement}
     */
    getTreeRef(){
      return this.$refs.tree;
    }
  }
};
</script>


 

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

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

相关文章

论文阅读:Dual-disentangled Deep Multiple Clustering

目录 摘要 引言 模型 实验 数据集 实验结果 结论 摘要 多重聚类近年来引起了广泛关注&#xff0c;因为它能够从不同的角度揭示数据的多种潜在结构。大多数多重聚类方法通常先通过控制特征之间的差异性来提取特征表示&#xff0c;然后使用传统的聚类方法&#xff08;如 …

SQL 复杂查询

目录 复杂查询 一、目的和要求 二、实验内容 &#xff08;1&#xff09;查询出所有水果产品的类别及详情。 查询出编号为“00000001”的消费者用户的姓名及其所下订单。&#xff08;分别采用子查询和连接方式实现&#xff09; 查询出每个订单的消费者姓名及联系方式。 在…

thread_id_key != 0x7777(`fibers` 包与 Node.js 16 及以上版本存在兼容性问题)

文章目录 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性1. Node.js 版本兼容性2. 特定包版本 (fibers4.0.3)3. 解决方案和替代方案 结论解决方案 运行yarn serve 启动项目&#xff0c;就会弹出上述错误。 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性 要判断 fibers4.0.3…

数据结构 (6)栈的应用举例

1. 递归调用 递归函数在执行时&#xff0c;会将每一层的函数调用信息&#xff08;包括局部变量、参数和返回地址&#xff09;存储在栈中。当递归函数返回时&#xff0c;这些信息会从栈中弹出&#xff0c;以便恢复之前的执行状态。栈的后进先出&#xff08;LIFO&#xff09;特性…

网络安全在数字时代保护库存数据中的作用

如今&#xff0c;通过软件管理库存已成为一种标准做法。企业使用数字工具来跟踪库存水平、管理供应链和规划财务。 然而&#xff0c;技术的便利性也带来了网络威胁的风险。黑客将库存数据视为有价值的目标。保护这些数据不仅重要&#xff0c;而且必不可少。 了解网络安全及其…

php常用伪协议整理

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理php常见的伪协议 php伪协议介绍 直观点&#xff0c;就是php可以识别的协议。 类似于我们访问网站的http协议&#xff0c;我们用浏览器访问我们自己本地文件的file协议等。 php可以识别这些协议&#xf…

【软件入门】Git快速入门

Git快速入门 文章目录 Git快速入门0.前言1.安装和配置2.新建版本库2.1.本地创建2.2.云端下载 3.版本管理3.1.添加和提交文件3.2.回退版本3.2.1.soft模式3.2.2.mixed模式3.2.3.hard模式3.2.4.使用场景 3.3.查看版本差异3.4.忽略文件 4.云端配置4.1.Github4.1.1.SSH配置4.1.2.关联…

【SpringBoot】28 API接口防刷(Redis + 拦截器)

Gitee仓库 https://gitee.com/Lin_DH/system 介绍 常用的 API 安全措施包括&#xff1a;防火墙、验证码、鉴权、IP限制、数据加密、限流、监控、网关等&#xff0c;以确保接口的安全性。 常见措施 1&#xff09;防火墙 防火墙是网络安全中最基本的安全设备之一&#xff0c…

零基础学安全--shell脚本学习(1)脚本创建执行及变量使用

目录 学习连接 什么是shell shell的分类 查看当前系统支持shell 学习前提 开始学习 第一种执行脚本方法 ​编辑 第二种执行脚本方法 第三种执行脚本方法 变量声明和定义 ​编辑 查看变量 删除变量 学习连接 声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣…

基于FPGA的FM调制(载波频率、频偏、峰值、DAC输出)-带仿真文件-上板验证正确

基于FPGA的FM调制-带仿真文件-上板验证正确 前言一、FM调制储备知识载波频率频偏峰值个人理解 二、代码分析1.模块分析2.波形分析 总结 前言 FM、AM等调制是学习FPGA信号处理一个比较好的小项目&#xff0c;通过学习FM调制过程熟悉信号处理的一个简单流程&#xff0c;进而熟悉…

“AI玩手机”原理揭秘:大模型驱动的移动端GUI智能体

作者&#xff5c;郭源 前言 在后LLM时代&#xff0c;随着大语言模型和多模态大模型技术的日益成熟&#xff0c;AI技术的实际应用及其社会价值愈发受到重视。AI智能体&#xff08;AI Agent&#xff09;技术通过集成行为规划、记忆存储、工具调用等机制&#xff0c;为大模型装上…

路由策略与路由控制实验

AR1、AR2、AR3在互联接口、Loopback0接口上激活OSPF。AR3、AR4属于IS-IS Area 49.0001&#xff0c;这两者都是Level-1路由器&#xff0c;AR3、AR4的系统ID采用0000.0000.000x格式&#xff0c;其中x为设备编号 AR1上存在三个业务网段A、B、C&#xff08;分别用Loopback1、2、3接…

uniapp开发微信小程序笔记8-uniapp使用vant框架

前言&#xff1a;其实用uni-app开发微信小程序的首选不应该是vant&#xff0c;因为vant没有专门给uni-app设置专栏&#xff0c;可以看到目前Vant 官方提供了 Vue 2 版本、Vue 3 版本和微信小程序版本&#xff0c;并由社区团队维护 React 版本和支付宝小程序版本。 但是vant的优…

Qt-系统相关(1)事件文件

Qt事件 事件介绍 事件是应⽤程序内部或者外部产⽣的事情或者动作的统称。在 Qt 中使⽤⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当⽤⼾按下⿏标、敲下键盘&#xff0c;或者是窗⼝需要重新绘制的时候&a…

HarmonyOS4+NEXT星河版入门与项目实战(20)------状态管理@ObjectLink @Observed

文章目录 1、用法图解2、案例实现1、任务类改造2、参数改造变量3、完整代码4、运行效果4、总结1、用法图解 2、案例实现 上一节的案例中,一直有一个功能没有生效,就是任务完成后对应的任务行变灰,任务字体出现中划线删除的效果。而该功能一直不生效的原因就是要改变的数据值…

【小白学机器学习36】关于独立概率,联合概率,交叉概率,交叉概率和,总概率等 概念辨析的例子

目录 1 先说结论 2 联合概率 3 边缘概率 4 (行/列)边缘概率的和 总概率1 5 条件概率 5.1 条件概率的除法公式 5.2 条件概率和联合概率区别 1 先说结论 关于独立概率&#xff0c;联合概率&#xff0c;交叉概率&#xff0c;交叉概率和&#xff0c;总概率 类型含义 …

TCP IP协议和网络安全

传输层的两个协议&#xff1a; 可靠传输 TCP 分段传输 建立对话&#xff08;消耗系统资源&#xff09; 丢失重传netstat -n 不可靠传输 UDP 一个数据包就能表达完整的意思或屏幕广播 应用层协议&#xff08;默认端口&#xff09;&#xff1a; httpTCP80 网页 ftpTCP21验证用户身…

redmi 12c 刷机

刷机历程 一个多月前网购了redmi 12c这款手机, 价格只有550,用来搞机再适合不过了, 拆快递后就开始倒腾,网上有人说需要等7天才能解锁,我绑定了账号过了几天又忍不住倒腾,最后发现这块手机不用等7天解锁成功了,开始我为了获取root权限, 刷入了很火的magisk,但是某一天仍然发现/…

分布式在线评测系统

OnlineJudge 前言所用技术开发环境 1. 需求分析2. 项目宏观结构3. compile_server服务设计3.1 compiler服务设计3.2 runner服务设计3.3 compile_run3.4 compile_server.cpp 4. oj_server服务设计4.1 model设计4.2 view设计4.3 control设计4.3.1 获取题目列表功能4.3.2 获取单个…

政安晨【零基础玩转各类开源AI项目】探索Cursor-AI Coder的应用实例

目录 Cusor的主要特点 Cusor实操 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; Cursor 是 Visual Studio Code 的一个分支。这使我们能够…