vue3自定义实现可过滤关键字的树形下拉选择框

背景

最近项目中有一个部门选择需求,一开始是用element-plus的级联下拉写的,但是由于层级过深,会出现级联下拉超出屏幕的情况,所以改用树形下拉,但是element没有相关组件,现记录下vue3+js自定义实现可以根据关键字筛选的树形下拉选择框。

实现效果

在这里插入图片描述

代码

<template>
  <el-popover popper-class="tree-select-popper el-select-dropdown" :width="width" trigger="click">
    <template #reference>
      <div
        ref="selectRef"
        class="tree-select el-select"
        :class="[elFormltemSize ? 'el-select--' + elFormltemSize : '']"
      >
        <overlay-scrollbars class="tree-select-input">
          <div :class="{ 'is-placeholder': !treeSelectText }" class="input-content">
            {{ treeSelectText || placeholder }}
          </div>
        </overlay-scrollbars>
      </div>
    </template>
    <div class="tree-select_wrapper">
      <div class="tree-search_input">
        <el-input v-model="treeFilterText" class="" placeholder="筛选" />
      </div>
      <overlay-scrollbars class="tree-scroll">
        <div class="select-tree-box">
          <el-tree
            ref="selectTree"
            :node-key="nodeKey"
            :current-node-key="modelValue"
            :data="data"
            :props="treeProps"
            :expand-on-click-node="false"
            class="select-tree"
            :filter-node-method="filterTreeNode"
            @node-click="handleClickTreeNode"
          />
        </div>
      </overlay-scrollbars>
    </div>
  </el-popover>
</template>
<script setup>
  import { computed, inject, nextTick, ref, watch } from 'vue';

  import { useElementSize } from '@vueuse/core';
  const props = defineProps({
    modelValue: {
      type: String,
      required: true,
    },
    size: String,
    data: {
      type: Array,
      default: () => [],
    },
    props: {
      type: Object,
      default: () => ({}),
    },
    placeholder: String,
    searchPlaceholder: String,
    nodeKey: {
      type: String,
      default: 'id',
    },
  });
  const emits = defineEmits(['update:modelValue']);
  const treeProps = computed(() => ({
    label: 'label',
    id: 'id',
    children: 'children',
    ...props.props,
  }));
  const elFormltem = inject('elFormltem');
  const elFormltemSize = computed(() => elFormltem?.size); //大小

  //选中的label
  const treeSelectText = computed(() => {
    let text = '';
    const getTreeSelectData = (arr, id, textArr) => {
      for (const item of arr) {
        if (item[treeProps.value.id] === id) {
          text = [...textArr, item[treeProps.value.label]].join('/');
          return;
        }
        if (!item[treeProps.value.children] || !item[treeProps.value.children]?.length) continue;
        getTreeSelectData(item[treeProps.value.children], id, [
          ...textArr,
          item[treeProps.value.label],
        ]);
      }
    };
    getTreeSelectData(props.data, props.modelValue, []);
    return text || props.modelValue;
  });
  //选中某个节点
  const handleClickTreeNode = (node) => {
    emits('update:modelValue', node[treeProps.value.id]);
  };
  const selectTree = ref(null);
  const treeFilterText = ref(''); //过滤树文字
  //节点过滤
  const filterTreeNode = (value, data) => {
    if (!value) return true;
    return data.label.includes(value);
  };
  watch(treeFilterText, (val) => selectTree.value?.filter(val));
  const selectRef = ref(null);
  const { width } = useElementSize(selectRef);
  const expandParents = (node) => {
    if (!node) return;
    node.expanded = true;
    expandParents(node?.parent);
  };
  //选中节点初始化
  watch(
    () => props.modelValue,
    (value) => {
      if (!value) return;
      nextTick(() => {
        selectTree.value?.setCurrentKey(value);
        const node = selectTree.value?.getNode(value);
        expandParents(node?.parent);
      });
    },
    { immediate: true, flush: 'post' },
  );
</script>
<style scoped lang="scss">
  .tree-select {
    width: 100%;
    .tree-select-input {
      width: 100%;
      color: #c0c4cc;
      border-radius: 4px;
      border: 1px solid #8a99b0;
      .os-content {
        .input-content {
          line-height: 32px;
          height: 32px !important;
          overflow: visible;
          white-space: nowrap;
          padding: 0 11px !important;
          display: inline-block;
          color: #606266;
          font-size: 14px;
          &.is-placeholder {
            color: #7f8da5;
          }
        }
      }
    }
  }
  .tree-select_wrapper {
    max-height: 271px;
    display: flex;
    flex-direction: column;
    .tree-search_input {
      flex: 0 0 auto;
      padding: 10px;
    }
    .tree-scroll {
      max-height: 271px;
      flex: 1;
      margin-top: 10px;
      .select-tree-box {
        padding: 0 10px 10px;
      }
      :v-deep(.select-tree) {
        .el-tree-node_children {
          overflow: visible !important;
        }
        .el-tree-node {
          &.is-current > .el-tree-node_content {
            color: $common;
          }
        }
      }
    }
  }
</style>
<style>
  .tree-select-popper {
    padding: O;
  }
</style>

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

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

相关文章

Vector - CAPL - CRC算法介绍(续)

不常用CRC算法 目录 Crc_CalculateCRC8H2F 代码示例 Crc_CalculateCRC32P4 代码示例 Crc_CalculateCRC64 代码示例 Crc_CalculateCRC8H2F 功能&#xff1a;根据数据计算CRC8H2F的相应校验和。 data&#xff1a;待计算CRC8H2F校验和的数据 dataSize&#xff1a;待计算CRC…

JVM垃圾收集器与HotSpot的算法细节

目录 HotSpot的算法细节实现 根节点枚举 安全点 安全区域 记忆集与卡表 记忆集 作用 卡表&#xff08;Card Table&#xff09; 卡页&#xff08;Card Page&#xff09; 元素变脏&#xff08;Dirty&#xff09; 写屏障 写屏障 写前屏障&#xff08;Pre-Write Barrie…

【数据结构】顺序表

作者&#xff1a;日出等日落 专栏&#xff1a;数据结构 只有毅力才会使我们成功&#xff0c;而毅力的来源又在于毫不动摇&#xff0c;坚决采取为达到成功所需要的手段。 …

Ceph部署

1. 简介 Ceph是一个高性能、可扩容的分布式存储系统&#xff0c;它提供三大功能&#xff1a; 对象存储&#xff1a;提供RESTful接口&#xff0c;也提供多种编程语言绑定。兼容S3、Swift块存储&#xff1a;由RBD提供&#xff0c;可以直接作为磁盘挂载&#xff0c;内置了容灾机…

代码规范(以后会补充)

目录 为什么要规范代码 不规范的代码有什么特点 ​编辑 不规范的坏处 规范代码是什么样的 如何规范代码 1.代码中不要出现莫名其妙的数字 2.深度嵌套 3.注释 4.避免创建大函数 5.重复代码 6.变量命名 7.函数命名 8.命名时注意动词的使用 9. 常量值所有都大写 10. 避免变…

PMP备考资料:如何掌握PMP应考中的计算题?

计算题总体来说考得非常简单&#xff0c;题量也少&#xff0c;有时候只考3道、4道简单计算。所以这部分内容大家要细心严谨&#xff0c;不要因为粗心而丢掉分数。 01三点估算 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划…

映射的概念以及用法

映射的概念以及用法前言映射的定义映射的应用前言 在数学里&#xff0c;映射是个术语&#xff0c;指两个元素的集之间元素相互 “对应”的关系&#xff0c;为名词。映射&#xff0c;或者射影&#xff0c;在数学及相关的领域经常等同于函数&#xff0c;函数是从非空数集到非空数…

PyCharm解决Git冲突

技术背景 在前面的一篇博客中&#xff0c;我们介绍了Fork到自己名下的本地仓库如何与远程原始仓库创建链接的方法。在这篇文章中&#xff0c;我们将要讲解如何应对在这种异步开发的过程中经常有可能会遇到的Git冲突问题&#xff0c;在Pycharm这个专业的Python开发工具中集成了一…

网络基础概念

本文目标&#xff1a; ①了解网络发展背景, 对局域网/广域网的概念有基本认识; ②了解网络协议的意义, 重点理解TCP/IP五层结构模型; ③学习网络传输的基本流程, 理解封装和分用; 1.计算机网络背景 OS与网络 在整个计算机体系中&#xff0c;是先由操作系统&#xff0c;再有网…

Windows下使用SSH密钥实现免密登陆Linux服务器

工具&#xff1a; win10、WinSCP 生成ssh密钥&#xff1a; 打开终端&#xff0c;使账号密码登录&#xff0c;输入命令 ssh-keygen -t rsa 会提示密钥存放路径&#xff0c;一般存放在默认路径&#xff0c;直接回车即可&#xff0c;中间会提示输入密码&#xff0c;这里需要注…

CC攻击原理以及如何防御策略

CC攻击原理以及如何防御策略 CC 攻击是一种 DDoS&#xff08;分布式拒绝服务&#xff09;&#xff0c;它似乎比其他 DDoS 攻击更具技术性。在这种攻击中&#xff0c;看不到假IP&#xff0c;看不到特别大的异常流量&#xff0c;但会导致服务器无法正常连接。 很多创业公司辛辛苦…

你是真的“C”——C语言测评总结

你是真的“C”——C语言测评总结&#x1f60e;前言&#x1f64c;BC146 添加逗号总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者简介&#xf…

TreEnhance: A Tree Search Method For Low-Light Image Enhancement 论文阅读笔记

这是2023年PR这个期刊的论文主要思想是&#xff0c;利用一系列预定义好的操作序列来进行增强&#xff0c;然后利用强化学习来学习增强序列的预测。所以训练阶段有两个交替进行的阶段&#xff0c;一个是蒙特卡洛树搜索阶段&#xff0c;第二个是训练深度强化学习的阶段。而测试的…

中级软件设计师备考---计算机组成与体系结构3

目录①磁盘工作原理②计算机总线③系统可靠性分析④校验码CRC循环校验码海明校验码①磁盘工作原理 计算题 ②计算机总线 概念题 ③系统可靠性分析 计算可靠度 ④校验码 码距&#xff1a;是指两个码字之间的不同位数。例如&#xff0c;1010和1111之间的码距是2&#xff0c…

160. 相交链表 ——【Leetcode每日一题】

160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c…

生成式人工智能所面临的问题有哪些?

在生成式人工智能中工作需要混合技术、创造性和协作技能。通过发展这些技能&#xff0c;您将能够在这个令人兴奋且快速发展的领域应对具有挑战性的问题。 生成式人工智能是指一类机器学习技术&#xff0c;旨在生成与训练数据相似但不完全相同的新数据。 换句话说&#xff0c;…

【二分—STL】lower_bound()函数upper_bound()函数的使用总结

目录一、基本用法&#xff1a;二、具体到题目中如何应用1、数的范围2、递增三元组3、数组元素的目标和一、基本用法&#xff1a; lower_bound() 用于二分查找区间内第一个 大于等于某值(> x) 的迭代器位置 upper_bound() 用于二分查找区间内第一个 大于某值(> x) 的迭代器…

IP协议以及相关技术

这里写目录标题前言正文IP基本认识IP的作用IP和MAC的关系IP地址的基础知识IP地址定义IP地址分类(IPv4)无分类IP地址CIDR子网掩码IPv6基础知识相关技术DNS域名解析ARPDHCPNATICMPIGMP总结参考连接前言 大家好&#xff0c;我是练习两年半的Java练习生&#xff0c;今天我们来讲一…

Meta AI Segment Anything Model (SAM)初体验

最近Meta AI发布了Segment Anything模型&#xff0c;可以直接分割任何图片。我趁热乎体验了一下。 文章目录进入官网 & 上传图片Hover & Click——截取物体Box——框选物体Everything——提取所有物体Cut-Outs——提取结果进入官网 & 上传图片 打开Segment Anythi…

JMP指令寻址方式总结,JMP BX指令寻址方式是什么

jmp 指令的几种寻址方式 jmp short 标号 段间跳转 -128-127 jmp far ptr 标号 超段转移 跳转包含目标地址jmp reg 16位寄存器 jmp word ptr 内存单元地址 段内转移 jmp dword ptr 内存单元地址 ( 段间转移) 高字地址存放cs 低字节存放ip jmp指令用法总结 1.直接用法(只能在Deb…