Element-ui下拉框多选样式——宽高自适应

Element-ui下拉框多选样式——宽高自适应

高度自适应

在element-ui的文档中可以看到,多选时,高度自适应是默认就有的展示方式,select组件不需要设置额外属性,如下图显示:
在这里插入图片描述

<el-select class="select" v-model="value" multiple placeholder="请选择">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
  </el-option>
</el-select>

正常情况下高度自适应已经足够使用了,但是如果option文字过多,tag横向展示时,就会出现超出输入框的异常显示情况,如下图所见:
在这里插入图片描述
解决方法:
修改css样式,修改tag宽度样式,增加文字超出显示省略号,代码如下:

<style lang="scss" scoped>
.el-select.select{
  ::v-deep .el-select__tags {
    .el-tag {
      display: flex;
      align-items: center;
      width: auto !important;
      max-width: 100% !important;
      flex-wrap: nowrap !important;
      .el-select__tags-text {
        flex: 1;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        display: block;
      }
    }
  }
}
</style>

效果显示如下,当option宽度大于选择框宽度时,tag内部显示省略号:
在这里插入图片描述

宽度自适应

宽度自适应和高度自适应是二选一的,所以宽度自适应的时候给高度增加限制,然后计算tag的宽度来实现宽度自适应;
解决方法:

<el-select
  ref="select"
  v-model="selectVal"
  class="select"
  multiple
  :class="{isAutoWidth: isAutoWidth}"
  :style="{'width': `${selectWid}px !important`}"
  :collapse-tags="!isAutoHeight && !isAutoWidth"
>
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
  </el-option>
</el-select>

监听value值的变化,计算每一个tag的宽度总和,包括内外边距、边框宽度,动态绑定,如下:

  data() {
    return {
      isAutoWidth: true, // 判断是否为宽度自适应
      selectWidth: 206, // select框默认宽度
      selectWid: 0, // 实际宽度
      padRight: 0, // input的padding-right
      itemsMLeft: 0, // tag之间的margin
      itemsMRight: 0, // tag之间的margin
      borderL: 0, // input边框
      borderR: 0, // input边框
      itemBborderL: 0, // tag边框
      itemBborderR: 0, // tag边框
    }
  },
  watch: {
    // select框最小宽度
    selectWidth: {
      deep: true,
      handler(n) {
        this.selectWid = n;
      },
      immediate: true
    },
    value: {
      deep: true,
        handler(n) {
          this.$nextTick(()=> {
            // 获取全部tag的vnode
            const tagArr = this.$refs.select.$children[0].$children;
            // querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。
            const childTag = this.$refs.select.$el.querySelectorAll('.el-tag');
            // 获取每个tag的宽度
            // clientWidth: 实际显示宽度+padding
            // offsetWidth: 实际显示宽度+padding+border
            const tagWidArr = tagArr.map(item=> {
              return item.$el.clientWidth;
            });
            // tag总宽度
            let allWid = 0;
            const tagMargin = this.itemsMLeft + this.itemsMRight; // tag之间的margin
            const tabBorder = this.itemBborderL + this.itemBborderR; // tag边框
            const inpBorder = this.borderL + this.borderR; // input边框
            tagWidArr.forEach(item=> {
              allWid += (item + tagMargin + tabBorder); // tagMargin为tag之间的margin, 2为border
            });
            const tagWid = allWid + this.padRight; // 30为input padding-right
            // 判断是否为宽度自适应需求
            if (this.isAutoWidth) {
              this.selectWid = (allWid > this.selectWidth) ? tagWid : this.selectWidth;
            } else {
              this.selectWid = this.selectWidth;
              // 这个功能是用来使显示不开的第一个tag进行省略号处理
              if (childTag.length) {
                childTag.forEach((item, index)=> {
                  let tagBoxWid = 0;
                  /**
                   * 8*2代表两个tag的margin + border
                   * padRight 代表input内边距
                   * 2写死的,这个是显示一个显示不开的那种情况(某个border)
                   */
                  if (this.isAutoHeight) {
                    tagBoxWid = this.selectWid - (tagMargin + tabBorder) - this.padRight - inpBorder;
                  } else {
                    // tag显示collapse-tags合并样式
                    tagBoxWid = childTag.length === 1 ?
                      this.selectWid - (tagMargin + tabBorder) - this.padRight - inpBorder :
                      this.selectWid - childTag[1].clientWidth - (tagMargin + tabBorder) * 2 - this.padRight - inpBorder;
                  }
                  item.style.maxWidth = tagBoxWid + 'px';
                });
              }
            }
		}
  	}
  }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值