首页 > 其他分享 >el-select组件改造成多选显示多个标签加数字标签的形式

el-select组件改造成多选显示多个标签加数字标签的形式

时间:2023-01-13 11:57:35浏览次数:59  
标签:el style 标签 value let 成多选 display select

接到需求需要只在一行内显示多个标签,且标签超出输入框时超出的标签不显示,只显示统计数字的标签。

效果图:

 

网上查资料,发现一篇大佬的文章跟该需求很类似,就借用了大佬的写法,文章链接看这里

后面发现还是有两个地方需要做下微调整。

1、需要数字标签紧跟着文字标签的后面排列,不能一直固定在右边

2、当页面同时有多个el-select组件时目前的写法会监听不到我们想监听的el-select组件,所以必须要保证被监听的组件的唯一性

调整后的代码如下:

html

    <el-select
      v-model="values"
      multiple
      style="width:100%"
      placeholder="请选择"
      @change="handleChange"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
      </el-option>
    </el-select>

props

    props: {
      options: {
        type: Array,
        default: () => []
      },
      value: {
        type: Array,
        default: () => []
      }
    }

  

mounted

    mounted() {
      let tagLIstDom = document.querySelector(".el-select__tags");
    //   需要加上组件自定义的类名,防止监听失效
      let tagSpanDom = document.querySelector(".select-tags .el-select__tags > span"); 
      let hideDom = document.createElement("span");
      hideDom.classList = ["count-node"]; //设置样式
      tagSpanDom.append(hideDom); //插入到span中
      var config = { childList: true };
  
      // 当观察到突变时执行的回调函数
      var callback = function(mutationsList) {
        mutationsList.forEach(function(item, index) {
          if (item.type == "childList") {
            let tagList = item.target.childNodes;
            let tagWidth = 0; //标签总宽度
            let tagNum = 0; //标签多余个数
            let avaliableTagWidth = 0 //显示标签的总宽度
            for (let i = 0; i < tagList.length; i++) {
              const e = tagList[i];
              if (tagWidth > tagLIstDom.offsetWidth) {
                e.style.display = "none"; //隐藏多余标签
              } else {
                e.style.display = "inline-block"; //显示标签
              }
              tagWidth += e.offsetWidth + 5;
              if (tagWidth > tagLIstDom.offsetWidth) {
                e.style.display = "none"; //隐藏多余标签
              } else {
                e.style.display = "inline-block"; //显示标签
              }
              if (e.style.display != "none") {
                tagNum++;
                hideDom.style.display = "none"; //隐藏多余标签个数
                const margin = tagNum === 1 ? 0 : 7
                avaliableTagWidth += e.offsetWidth + margin
              } else {
                hideDom.style.display = "inline-block"; //显示多余标签个数
                hideDom.style.left = `${avaliableTagWidth}px` //数字标签的位置设置
                hideDom.innerHTML = `+${tagList.length - tagNum}`;  //显示多余标签个数
              }
            }
          }
        });
      };
  
      // 创建一个链接到回调函数的观察者实例
       observer = new MutationObserver(callback);
  
      // 开始观察已配置突变的目标节点
      observer.observe(tagSpanDom, config);
  
      // 随后,您还可以停止观察
      // observer.disconnect();
    },

  

其他

    methods: {
      handleChange() {
        this.$emit("change", this.value);
      }
    },
    computed: {
      values: {
        get() {
          return this.value;
        },
        set(val) {
          this.$emit("input", val);
        }
      }
    },
    //销毁时
    beforeDestroy() {
      // 停止观察
      observer.disconnect();
    }

  

style

  <style>
 .count-node {
    position: absolute;
    top: 2px;
    display: none;
    height: 24px;
    padding: 0 8px;
    line-height: 22px;
    margin-left: 6px;
    background-color: #f4f4f5;
    border: 1px solid #e9e9eb;
    border-radius: 4px;
    color: #909399;
    font-size: 12px;
    box-sizing: border-box;
  }
  </style>

 

父组件引用

html

设置的class类名‘select-tags’用于保证获取组件需要监听的元素的唯一性

      <select-tags
      v-model="value1"
      :options="options"
      class="select-tags"
      ></select-tags>

data

   options: [{
          value: '选项1',
          label: '黄金糕'
        }, {
          value: '选项2',
          label: '双皮奶'
        }, {
          value: '选项3',
          label: '蚵仔煎'
        }, {
          value: '选项4',
          label: '龙须面'
        }, {
          value: '选项5',
          label: '北京烤鸭'
        }],
        value1: [],

 参考资料链接 

 

标签:el,style,标签,value,let,成多选,display,select
From: https://www.cnblogs.com/applesky/p/17049175.html

相关文章

  • html基本标签
    <!DOCTYPEhtml><html><head> <metacharset="UTF-8"> <metaname="description"content="爱Zyn的一切"> <!--搜索内容描述--> <metaname="keywords"content=......
  • (六)elasticsearch 源码之选主流程分析
    1.概述es(elasticsearch,下同)的选举流程相对来说比较简单,使用的bully算法,简而言之,就是谁强谁就是老大,待会儿看下怎么判定谁更强。2.选主流程在启动篇中我们讲解了节点启动......
  • 特斯拉把超级工厂开到印尼,能让Model 3再降价1万
    控制成本,从掌握上游原材料做起。根据彭博社消息,特斯拉第四个超级工厂的选址有了新动向。消息称,特斯拉与印尼政府就在印尼建立超级工厂达成初步协议。特斯拉以及印......
  • 28、electron 发送http请求,数据接收不完整
    electron发送http请求,参考官网api:https://www.electronjs.org/zh/docs/latest/api/net#netrequestoptionshttps://www.electronjs.org/zh/docs/latest/api/client-requ......
  • WindTerm快速切换标签页
    默认使用Alt+[和Alt+]进行切换,如需修改常规的Ctrl+Tab进行如下操作找到快捷键配置文件WindTerm_2.6.0\global下的wind.keymaps并打开。如果找不到的话,用everything搜......
  • elasticsearch(es)根据指定字段去重查询
     distinctFieldName 就是去重字段,这个字段必须是keyword类型不然会报错 //指定去重字段CollapseBuildercollapseBuilder=newCollapseBuilder......
  • DPDK入门实践2——编译安装与helloworld
    要想弄懂一个工程,在了解完它的基本概念和大体架构之后,就让它跑起来。看看是怎么玩转的,然后再深入细节。这里我先到GitHub上下载dpdk工程的18.11.2稳定版本,之所以选择这个版......
  • 如何通过Java应用程序将Word转为Excel
    平时在工作中,很多小伙伴会习惯性地将文件保存为Word文档格式,但有时会发现某些文件如果保存成Excel表格可能会更好地呈现。例如有的文本在Word文本中不如在Excel工作表编辑计......
  • Selenium的webdriver下载地址汇总
    chromedriver驱动下载地址:(根据chrome版本下载)http://chromedriver.storage.googleapis.com/index.htmlmicrosoft-edge驱动下载地址:(根据Edge版本下载)https://developer.m......
  • selenium 爬豆瓣帖子
    #!/usr/bin/envpython3#-*-coding:utf-8-*-"""CreatedonMonAug3019:17:122021@author:ledi"""importtimeimportparselimportcsvfromseleniumimportwebdri......