基于Element UI内置的Select下拉和Tree树形组件,组合封装的树状下拉选择器

news2024/11/14 2:51:08

目录

简述

效果

功能描述

代码实现

总结


简述

基于Element UI内置的Select下拉和Tree树形组件,组合封装的树状下拉选择器。

效果

先看效果:

下拉状态:

选择后状态:

选择的数据:

功能描述

1、加载树结构,实现树状下拉选择器; 

2、可通过关键词实现本地和远程过滤; 

3、高亮选择行; 

4、设置默认选择行; 

5、可直接应用在form表单;

代码实现

树状下拉组件代码:

<!--
 树状下拉选择框:
 1、加载树结构,实现树状下拉选择组件;
 2、可通过关键词实现本地和远程过滤;
 3、高亮选择行;
 4、设置默认选择行;
 5、可直接应用在form表单;
-->
<template>
  <el-select
      ref="selectRef"
      clearable
      filterable
      :remote="remote"
      :remote-method="selectRemoteMethod"
      v-model="currentLabel"
      @visible-change="handleVisibleChange"
      @clear="handleClear"
  >
    <el-option
        style="height: 100%; padding: 0"
        value=""
        v-loading="loading"
        element-loading-text="加载中..."
        element-loading-spinner="el-icon-loading"
    >
      <el-tree
          ref="treeRef"
          :data="dataOfTree"
          :node-key="defaultProps.value"
          :props="defaultProps"
          highlight-current
          default-expand-all
          :current-node-key="selectedNode.value"
          :expand-on-click-node="false"
          @node-click="handleNodeClicked"
          :filter-node-method="filterNode"
      >
      </el-tree>
    </el-option>

  </el-select>
</template>
<script>

export default {
  name: 'SelectTree',
  components: {},
  model: {
    prop: 'inputValue',
    event: 'myInputEvent'
  },
  props: {
    // 默认选中值
    defaultValue: {
      type: Number
    },
    // 是否远程搜索
    remote: {
      type: Boolean,
      default: false
    },
    // 远程方法
    remoteMethod: {
      type: Function
    },
    treeOptions: {
      type: Array,
      default: () => {
        return []
      }
    },
    defaultProps: {
      type: Object,
      default: () => {
        return {
          children: 'children',
          label: 'label',
          value: 'value'
        }
      }
    }
  },
  watch: {
    treeOptions: {
      handler(newValue) {
        this.dataOfTree = JSON.parse(JSON.stringify(newValue))
        // 保留源数据;
        this.dataSource = JSON.parse(JSON.stringify(newValue))
      },
      deep: true,
      immediate: false
    },
    defaultValue: {
      handler(newValue) {
        this.selectedNode = {}
        this.currentLabel = undefined
        this.currentValue = newValue
        this.$nextTick(() => {
          // 过滤方式是通过value还是label;
          this.isFilterWithValue = true
          if (this.dataOfTree) {
            this.$refs.treeRef.filter(newValue)
          }
        })
      },
      deep: true,
      immediate: true
    }
  },
  data() {
    return {
      selectedNode: {},
      loading: false,
      currentValue: undefined,
      currentLabel: undefined,
      dataOfTree: []
    }
  },
  created() {
    this.dataOfTree = JSON.parse(JSON.stringify(this.treeOptions))
    // 保留源数据;
    this.dataSource = JSON.parse(JSON.stringify(this.treeOptions))
  },
  mounted() {
  },
  methods: {
    selectRemoteMethod(val) {
      this.isFilterWithValue = false
      if (this.remote) {
        // 远程搜索
        this.remoteMethod(val)
      } else {
        // 本地过滤
        this.$refs.treeRef.filter(val)
      }
    },
    handleClear() {
      // 如果内容被清空
      this.selectedNode = {}
      this.currentLabel = undefined
      this.currentValue = undefined
      this.$emit('myInputEvent', {node: undefined, data: {label: undefined, value: undefined}, meta: undefined})
      this.$emit('onNodeSelectEvent', {node: undefined, data: {label: undefined, value: undefined}, meta: undefined})
    },
    handleVisibleChange(visible) {
      if (!visible) {
        // 先移除所有数据;
        this.dataOfTree.splice(0)
        // 恢复原来的所有数据;
        this.dataOfTree.splice(0, 0, ...this.dataSource)
        // 本地过滤
        this.$refs.treeRef.filter('')
      }
    },
    filterNode(value, data) {
      if (!value) {
        return data
      }
      if (this.isFilterWithValue) {
        if (data[this.defaultProps.value] === value) {
          this.selectedNode = data
          this.currentLabel = data[this.defaultProps.label]
          this.$refs.treeRef.setCurrentKey(this.selectedNode[this.defaultProps.value])
          this.$emit('myInputEvent', {
            node: data[this.defaultProps.value],
            data: {label: data[this.defaultProps.label], value: data[this.defaultProps.value]},
            meta: data
          })
        }
      } else {
        return data[this.defaultProps.label].indexOf(value) !== -1
      }
      return data
    },
    closeSelect() {
      this.$refs.selectRef.blur()
    },
    /**
     * @param data
     * @param node
     * @param comp
     */
    handleNodeClicked(data, node, comp) {
      this.selectedNode = data
      this.currentLabel = data[this.defaultProps.label]
      this.currentValue = data[this.defaultProps.value]
      this.$emit('myInputEvent', {
        node: data[this.defaultProps.value],
        data: {label: data[this.defaultProps.label], value: data[this.defaultProps.value]},
        meta: data
      })
      this.$emit('onNodeSelectEvent', {
        node: data[this.defaultProps.value],
        data: {label: data[this.defaultProps.label], value: data[this.defaultProps.value]},
        meta: data
      })
      this.closeSelect()
    }
  }
}
</script>

<style lang='scss' scoped>
</style>

应用示例:

<template>
  <div>
    <div>测试表单</div>
    <el-form
        ref="demandFormRef"
        :model="form"
        label-suffix=":"
        status-icon
        label-position="left"
    >
      <el-form-item label="树" label-width="85px" prop="tree">
        <select-tree
            v-model="form.tree"
            :tree-options="treeOptions"
            :default-value="form.tree.node"
            @onNodeSelectEvent="handleNodeSelectEvent($event)"
        />
      </el-form-item>
    </el-form>
    <div>
      <el-button @click="reset">重置</el-button>
      <el-button @click="submit">提交</el-button>
    </div>
  </div>
</template>
<script>
import {Message} from 'element-ui'
import SelectTree from '@/components/SelectTree/index'

export default {
  components: {
    SelectTree
  },
  props: {},
  data() {
    return {
      form: {
        tree: {node: undefined, data: {}}
      },
      treeOptions: [{
        value: 1,
        label: '一级 1',
        children: [{
          value: 11,
          label: '二级 1-1',
          children: [{
            value: 111,
            label: '三级 1-1-1'
          }]
        }]
      }, {
        value: 2,
        label: '一级 2',
        children: [{
          value: 21,
          label: '二级 2-1'
        }]
      }, {
        value: 3,
        label: '一级 3',
        children: [{
          value: 31,
          label: '二级 3-1',
          children: [{
            value: 311,
            label: '三级 3-1-1'
          }]
        }, {
          value: 32,
          label: '二级 3-2',
          children: [{
            value: 321,
            label: '三级 3-2-1'
          }]
        }]
      }]
    }
  },
  mounted() {
    // 模拟接口请求,反显选择数据
    // setTimeout(() => {
    //   this.form.tree.node = 2
    // }, 1000)
  },
  methods: {
    reset() {
      this.form.tree = {node: undefined, data: {}}
    },
    submit() {
      const data = this.form.tree.data
      Message.info(`选中节点名称是${data.label},值是${data.value}`)
    },
    handleNodeSelectEvent(dataSelected){
    }
  }
}
</script>

<style lang='scss' scoped>
</style>

总结

本示例中,部分实现细节或者写法,可根据实际需要调整,树状下拉的实现方式有多种,这只是其中一种,只要符合实际需求就可以。

如果发现问题,欢迎随时提出,共同改进。

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

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

相关文章

Python 使用TCP\UDP协议创建一个聊天室

server端代码&#xff1a; #encodingutf-8 # 服务端代码 import socketdef server():server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM)host socket.gethostname()port 12345server_socket.bind((host, port))server_socket.listen(5)print(等待客户端连接…

如何通过一条SQL变更多个分库分表?

数据库发展到今天&#xff0c;分库分表已经不是什么新鲜话题了&#xff0c;传统的单节点数据库架构在数据量和访问频次达到一定规模时&#xff0c;会出现性能瓶颈和扩展性问题&#xff0c;而分库分表技术通过将数据分散到多个数据库实例中来分担负载&#xff0c;从而提升系统的…

粮信甄选·非凡凸现|携手中粮期货、国信证券共同见证数智交易前沿力量

近日&#xff0c;中粮期货、国信证券联合非凸科技在深圳举办了“粮信甄选&#xff0c;非凡凸现”主题机构洽谈会&#xff0c;与行业专家、私募管理人共同探讨如何推进产业与金融的深度融合&#xff0c;以及实现科技创新与生态合作的新模式。 近年来&#xff0c;国信证券始终聚…

开源物联网网关ThingsBoard IoT Gateway

前几天测试了Neuron&#xff0c;这是一个令人印象深刻的平台&#xff0c;不过它不能算是完全免费的平台&#xff0c;因为它还是有商业许可要求的&#xff0c;挺贵的&#xff0c;大几万的&#xff0c;而且它有走向闭源的趋势。所以也在寻找它的替代方案。 今天看到一个ThingsBo…

最新全新UI异次元荔枝V4.4自动发卡系统源码

简介&#xff1a; 最新全新UI异次元荔枝V4.4自动发卡系统源码 更新日志&#xff1a; 1增加主站货源系统 2支持分站自定义支付接口 3目前插件大部分免费 4UI页面全面更新 5分站可支持对接其他分站产品 6分站客服可自定义 7支持限定优惠 图片&#xff1a; 会员中心截图&…

王春城 | TPM是如何减少设备停机时间的?

在快节奏的生产环境中&#xff0c;设备停机时间无疑是每个企业都头疼的问题。它不仅影响生产效率&#xff0c;还可能造成巨大的经济损失。那么&#xff0c;有没有一种神奇的方法能够一键减少设备停机时间呢&#xff1f;答案就是--TPM&#xff08;全面生产维护&#xff09;&…

【区块链+绿色低碳】双碳数字化管控平台 | FISCO BCOS应用案例

地方政府、园区及企业实现“双碳”目标过程中存在一些挑战与难点&#xff1a; 1. 管理者难以掌握完整、准确、全面的碳排放数据进行科学决策&#xff1a;由于碳排放核算需要对数据的来源、核算方法 的规范性和采集方法的科学性有严格要求&#xff0c;当前面临碳排放数据数据采…

什么是PCB盲孔、埋孔和电镀孔?

PCB有不同类型的孔&#xff0c;根据孔贯穿PCB内外层的层次&#xff0c;孔可分为通孔、埋孔和盲孔。 如您所知&#xff0c; PCB 由堆叠在一起的铜箔层组成.这些“过孔”连接PCB上的不同电路层。它类似于具有相互连接的隧道的地下系统。如果你玩过电子游戏“超级马里奥”&#xf…

基于web的物流配送管理系统/基于客户时间窗变化的物流配送管理系统/快递配送管理系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

springboot集成redis之字典缓存

什么是redis的字典缓存&#xff1f; Redis的缓存是Redis内部用于存储键值对数据结构的一种基础数据结构。在Redis中&#xff0c;所有的键值对都是通过字典这种数据结构来存储的。字典在Redis中扮演着核心角色&#xff0c;因为它不仅用于数据库中的键值对存储&#xff0c;还用于…

React 学习——条件渲染、遍历循环、事件绑定

React特点&#xff1a; 声明式的设计高效&#xff0c;采用虚拟DOM来实现DOM的渲染&#xff0c;最大限度减少DOM的操作灵活&#xff0c;跟其他库灵活搭配使用JSX&#xff0c;俗称JS里面写HTML&#xff0c;JavaScript语法的扩展组件化&#xff0c;模块化&#xff0c;代码容易复用…

SQL labs-SQL注入(二)

环境搭建参考 SQL注入&#xff08;一&#xff09; 一&#xff0c;SQL labs-less2。 http://192.168.61.206:8001/Less-2/?id-1 union select 1,2,group_concat(username , password) from users-- 与第一关没什么太大的不同&#xff0c;唯一区别就是闭合方式为数字型。 二…

苹果笔记本电脑如何优化系统 苹果电脑系统优化软件哪个好 cleanmymac x怎么用

随着时间的推移&#xff0c;你可能会发现你的MacBook运行速度变慢&#xff0c;甚至在执行一些基本任务时也会感觉到卡顿。这不仅影响了工作效率&#xff0c;也大大降低了使用体验。但别担心&#xff0c;优化你的Mac系统比做早餐还简单。本文将用一种轻松的风格向你介绍7种简单易…

AI绘画入门实践|Midjourney:使用 --seed 制作情侣头像与漫画

在 Midjourney 中&#xff0c;seed 是指一个种子&#xff0c;用于生成图像时的起点或基础。 使用格式&#xff1a;--seed 获取的seed值 获取 seed 值 使用 seed 生成图像 a cute boys avatar, background with blue sky and white cloud, Ghibli Studio style, Hayao Miyazaki…

2024最新手机软件APP下载排行网站源码 软件下载站PHP源码

源码介绍 这是一款简洁蓝色的手机软件下载应用排行、平台和最新发布网站源码&#xff0c;主要包括主页、APP列表页、APP详情介绍页、新闻资讯列表、新闻详情页、关于我们等模块页面。 软件下载站PHP网站源码&#xff0c;简单的部署上线&#xff0c;访问首页安装程序&#xff…

Docker Desktop安装

0 Preface/Foreward 1 安装 1.1 运行docker安装包 安装完Docker Desktop后&#xff0c;运行Docker Desktop&#xff0c;出现WSL 2安装不完整情况&#xff0c;具体情况如下&#xff1a; 解决方法&#xff1a;旧版 WSL 的手动安装步骤 | Microsoft Learn 也可以直接下载新的安…

rce漏洞-ctfshow(50-70)

Web51 if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\|\%|\x09|\x26/i", $c)){ system($c." >/dev/null 2>&1"); } Nl&#xff0c;绕过tac&#xff0c;cat&#xff0c;绕…

YOLOv8高效涨点之改进主干RepLKNet

这篇文章讨论了在现代卷积神经网络(CNN)设计中使用大卷积核的优势,并提出了一种新的CNN架构RepLKNet。以下是对文章内容的分条说明: 大卷积核的优势:文章提出使用大卷积核(例如3131)而不是传统的小卷积核(如33)可以提供更强大的特征提取能力。 灵感来源:这种设计思路…

AI智能名片微信小程序在品牌战略与私域流量构建中的应用与深度探索

摘要&#xff1a;在数字经济时代&#xff0c;私域流量的价值日益凸显&#xff0c;成为企业和个人实现可持续增长的重要驱动力。品牌&#xff0c;作为私域流量的核心&#xff0c;其稳定性和影响力直接关系到流量的质量与转化效率。AI智能名片微信小程序&#xff0c;作为数字营销…

耳机、音响UWB传输数据模组,飞睿智能低延迟、高速率超宽带uwb模块技术音频应用

在数字化浪潮席卷全球的今天&#xff0c;无线通信技术日新月异&#xff0c;其中超宽带&#xff08;Ultra-Wideband&#xff0c;简称UWB&#xff09;技术以其独特的优势&#xff0c;正逐步成为无线传输领域的新星。本文将深入探讨飞睿智能UWB传输数据模组在音频应用中的创新应用…