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

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

    • 高度自适应
    • 宽度自适应

高度自适应

在element-ui的文档中可以看到,多选时,高度自适应是默认就有的展示方式,select组件不需要设置额外属性,如下图显示:
Element-ui下拉框多选样式——宽高自适应_第1张图片

<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横向展示时,就会出现超出输入框的异常显示情况,如下图所见:
Element-ui下拉框多选样式——宽高自适应_第2张图片
解决方法:
修改css样式,修改tag宽度样式,增加文字超出显示省略号,代码如下:


效果显示如下,当option宽度大于选择框宽度时,tag内部显示省略号:
Element-ui下拉框多选样式——宽高自适应_第3张图片

宽度自适应

宽度自适应和高度自适应是二选一的,所以宽度自适应的时候给高度增加限制,然后计算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';
                });
              }
            }
		}
  	}
  }

你可能感兴趣的:(element-ui,vue,ui,javascript,前端)