Vue combines element multi-selection to increase full selection

The overall effect is shown in the figure above

The parent component index.vue refers to the select file to pass the value

<template>
  <div class="clearfix">
    <select :optionData="provinceData" :selectList.sync="selectList" placeholderText="请选择"/>
  </div>
</template>

<script>
import selectfrom "@/components/select"
import areaJs from "@/assets/address"
export default {
  components: {
    select
  },
  data() {
    return {
      selectValue: '',
      provinceData: areaJs.data,
  }
};
</script>

Encapsulated select.vue file

<template>
  <div class="component-multipleSelect-wrap">
    <el-select 
    v-model='selectedArray' 
    @change='changeSelect' 
    multiple 
    :placeholder="placeholderText" 
    clearable 
    :popper-append-to-body="false"
    :class="{'single-select-search-wrap-nodata': options3[1].options.length === 0, 'single-select-search-height': isHeight}" 
    style="width: 150px"
    @visible-change="visibleChange">
      <el-option-group
        v-for="(group, index) in options3"
        :key="index"
        :label="group.label">
        <div class="select-search" v-if="index === 0">
          <div class="select-search-input">
            <el-input
            v-model="searchInput"
            placeholder="搜索"
            prefix-icon="el-icon-search"
            @change="searchInputChange"
            />
          </div>
          <div class="select-search-nodata" v-if="options3[1].options.length === 0">
            暂无数据
          </div>
        </div>
        <li class="el-select-dropdown__item"
        @click="selectAllrow"><el-checkbox v-model="checked" @change='selectAll' ssclass="checkbox-all" :indeterminate="isIndeterminate" v-if="options3[1].options.length > 0">全选</el-checkbox></li>
        <el-option
        v-for="item in group.options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
        >
          <span class="checkbox checkbox-false"></span>
          <span>{
   
   { item.label }}</span>
        </el-option>
      </el-option-group>
    </el-select>
  </div>
</template>

<script>
  export default {
  props: {
    selectList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    optionData: {
      type: Array,
      default: function() {
        return []
      }
    },
    placeholderText: {
      type: String,
      default: '请选择'
    }
  },
  
  watch: {
    optionData: {
      handler() {
        // console.log(this.optionData, '99999')
      }
    },
    searchInput: {
      handler() {
        // console.log(this.searchInput, '99999')
        this.flilterSelectData()
      }
    },
    selectedArray: {
      handler() {
        if(this.selectedArray.length === 0) {
          this.isHeight = true
        } else {
          this.isHeight = false
        }
      }
    },
  },
  data() {
    return {
      value6: [],
      optionsTwo: [
        {
          value: 1,
          label: "黄金糕"
        },
        {
          value: 2,
          label: "双皮奶"
        },
        {
          value: 3,
          label: "蚵仔煎"
        },
        {
          value: 4,
          label: "龙须面"
        },
        {
          value: 5,
          label: "北京烤鸭"
        }
      ],
      checkedTwo: true,
      checked: false,
      selectedArray: [],
      isIndeterminate: false,
      searchInput: '',
      options3: [{
        label: '',
        options: [{}]
      }, {
        label: '',
        options: []
      }],
      value7: '',
      oldOptionData: [],
      isHeight: true
    };
  },
  created() {

  },
  mounted() {
    if (this.optionData.length === 0) {
      this.options3[0].options = []
    }
    this.oldOptionData = this.optionData
    this.options3[1].options = this.optionData
  },
  methods: {
    selectAll() {
      this.selectedArray = []
      if (this.checked) {
        this.checked = true
        this.isIndeterminate = false
        this.options3[1].options.map((item) => {
          this.selectedArray.push(item.value)
        })
      } else {
        this.checked = false
        this.isIndeterminate = false
        this.selectedArray = []
      }
       this.$emit('update:selectList', this.selectedArray)
    },
    changeSelect(val) {
       this.$emit('update:selectList', val)
      if (val.length === this.options3[1].options.length) {
        this.checked = true
        this.isIndeterminate = false
      } else {
        this.checked = false
        if(val.length < this.options3[1].options.length) {
          this.isIndeterminate = true
        }
        if (val.length === 0) {
          // console.log(val)
          this.checked = false
          this.isIndeterminate = false
        }
      }
    },
    selectAllrow() {
      this.checked = !this.checked
      if (this.checked) {
        this.options3[1].options.map((item) => {
          this.selectedArray.push(item.value)
        })
      } else {
        this.selectedArray = []
      }
    },
    searchInputChange(val) {
      // console.log('searchInputChange', val)
    },
    // 过滤下拉选项的值
    flilterSelectData() {
      if (this.searchInput === '') {
        this.options3[1].options = this.oldOptionData
      } else {
        // var newarray = this.oldOptionData.filter(item => item.label.indexOf(this.searchInput) === 0)
        var newarray = this.oldOptionData.map(item => {
          if (item.label === this.searchInput || item.label.indexOf(this.searchInput) === 0) {
            return item;
          } else {
            for (var i = 0; i < item.label.length; i++) {
              if (item.label[i].indexOf(this.searchInput) >= 0) {
                return item;
              }
            }
          }
        }).filter(item => item)
        // console.log(newarray, 'newarray')
        this.options3[1].options = newarray
      }
    },
    visibleChange(val) {
      if (val) {
        this.$nextTick(() => {
          this.searchInput = ''
        })
      }
    }
  },
}
</script>

<style lang='scss' scoped>
@import "~@/styles/variables.scss";
.checkbox{
  display: inline-block;
  width: 14px;
  height: 14px;
  background-color: #fff;
  border: 1px solid #8C8C8C;
  border-radius: 2px;
  vertical-align: -2px;
  margin-right: 7px;
  &:hover{
    border: 1px solid $lightBlue;
  }
}
.select-search{
  .select-search-input{
    border-bottom: 1px solid #e8e8e8;
  }
}
.select-search-nodata{
  line-height: 32px;
  padding: 0px 10px;
  text-align: center;
  color: #999;
}
</style>

Reset the style inside the element

$lightBlue: blue;
// 下拉带复选框的样式重置
.component-multipleSelect-wrap{
  .el-checkbox__input.is-focus .el-checkbox__inner{
    border-color: $secondaryText !important;
  }
  
  .el-checkbox__input.is-checked .el-checkbox__inner{
    border-color: transparent !important;
  }
  .el-scrollbar__wrap{
    overflow: hidden;
  }
  .el-tag--small {
    padding: 0 3px;
  }
  .el-select .el-tag__close.el-icon-close{
    right: -2px;
  }
  .single-select-search-wrap-nodata{
    .el-select-group__wrap{
      &:nth-child(1) {
        height: 69px;
        overflow: hidden;
      }
      &:nth-child(2) {
        display: none;
      }
    }
  }
  .el-select-group__wrap{
    &:nth-child(1) {
      height: 33px;
      overflow: hidden;
    }
    &:nth-child(2) {
      width: 96%;
      margin: 0;
      padding: 0px 0px 12px 0px;
      overflow-y: scroll;
      height: 176px;
    }
  }
  .el-select-dropdown__list{
    padding: 0px;
  }
  .el-select-group__wrap:not(:last-of-type){
    padding-bottom: 0px;
  }
  .el-select-group__wrap:not(:last-of-type)::after{
    background-color: transparent;
  }
  .select-search{
    .el-input__inner{
      border: 1px solid transparent;
    }
    .el-input__prefix{
      top: -1px;
      left: 9px;
    }
    .el-input--prefix .el-input__inner{
      padding-left: 34px;
    }
  }
  .el-select-dropdown__item {
    overflow: visible;
    color: #606266;
  }

  .el-select-dropdown.is-multiple .el-select-dropdown__item.selected{
    .checkbox-false{
      position: relative;
      background: $lightBlue;
      border: 0px;
      &::after {
        position: absolute;
        top: -9px;
        right: 1px;
        color: #fff;
        font-family: element-icons;
        content: "\E611";
        font-size: 10px;
        font-weight: 400;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
      }
    }
  }

  .el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after {
      content: "";
  }
  .el-select-dropdown.is-multiple .el-select-dropdown__item.selected {
      color: $lightBlue;
  }
  .el-select-dropdown.is-multiple .el-select-dropdown__item.hover {
      background-color: #fff;
  }

  .el-select-dropdown__item{
    &:hover{
      background-color: #EAF5FCFF !important;
    }
  }

  .checkbox-all{
    .el-checkbox__input.is-checked+.el-checkbox__label {
      color: $lightBlue;
    }
  }

  .el-select .el-tag{
    border-color: transparent;
    background-color: #F5F5F5FF;
  }
  .el-tag--info, .el-tag--info .el-tag__close {
    color:  #595959FF;
  }
  .el-select .el-tag__close.el-icon-close {
    background-color: transparent;
  }
  .el-select .el-tag__close.el-icon-close::before{
    color: #000000FF;
  }
  .el-select-group .el-select-dropdown__item {
      padding-left: 10px;
  }
  .el-select-dropdown__item .el-checkbox__label{
    line-height: 1 !important;
    vertical-align: -2px;
  }
  .el-select-dropdown__item .el-checkbox__input{
    vertical-align: -4px;
  }
  .el-input--medium .el-input__inner {
      height: 32px;
      line-height: 32px;
  }

}

 

Guess you like

Origin blog.csdn.net/z1712636234/article/details/106238536
Recommended