Vue学习笔记【2】组件 - 多选select(带全选)

颜熙云
2023-12-01

创建组件

  1. 在 components 目录下创建组件 MultipleSelect.vue
  2. 组件代码
<template>
  <div style="display: flex">
    <el-select
      style="width: 300px"
      size="mini"
      multiple
      filterable
      :disabled="disabled"
      v-model='selectedArr'
      :loading="mulSelectLoading"
      :collapse-tags="collapseTags"
      placeholder='请选择'
      @change='changeSelect'
      @remove-tag='removeTag'>
      <el-option label='全选' value='全选' @click.native='selectAll' v-if="selectOptions.length"></el-option>
      <el-option v-for='item in selectOptions' :key='item.value' :label='item.label' :value='item.value'></el-option>
    </el-select>
  </div>
</template>

<script>
export default {
  name: 'MultipleSelect',
  data () {
    return {
      selectedArr: []
    }
  },
  props: {
    // 选项
    selectOptions: {
      type: Array,
      default () {
        return []
      }
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 已选中选项
    mulSelecteds: {
      type: Array,
      default () {
        return []
      }
    },
    mulSelectLoading: {
      type: Boolean,
      default: false
    },
    collapseTags: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    selectAll () {
      if (this.selectedArr.length < this.selectOptions.length) {
        this.selectedArr = []
        this.selectOptions.map((item) => {
          this.selectedArr.push(item.value)
        })
        this.selectedArr.unshift('全选')
      } else { // 取消全选
        this.selectedArr = []
      }
      this.$emit('update:updateMultipleSelect', this.selectedArr)
    },
    changeSelect (val) {
      if (!val.includes('全选') && val.length === this.selectOptions.length) {
        this.selectedArr.unshift('全选')
      } else if (val.includes('全选') && (val.length - 1) < this.selectOptions.length) {
        this.selectedArr = this.selectedArr.filter((item) => {
          return item !== '全选'
        })
      }
      this.$emit('update:updateMultipleSelect', this.selectedArr)
    },
    removeTag (val) {
      if (val === '全选') {
        this.selectedArr = []
        this.$emit('update:updateMultipleSelect', this.selectedArr)
      }
    }
  },
  watch: {
    mulSelecteds: {
      handler (newVal, oldVal) {
        this.selectedArr = newVal
        if (!this.selectedArr.includes('全选') &&
          this.selectedArr.length &&
          this.selectedArr.length === this.selectOptions.length) {
          this.selectedArr.unshift('全选')
        }
      },
      immediate: true
    }
  }
}
</script>
  1. 父组件中引用
<template>
  <div class="app">
      <el-card class="box-card">
              <MultipleSelect
                :selectOptions="selectOptions"
                :mulSelectLoading="mulSelectLoading"
                :mulSelecteds="mulSelecteds"
                @update:updateMultipleSelect="val => mulSelecteds = val">
              </MultipleSelect>
      </el-card>
  </div>
</template>
<script>
import MultipleSelect from './components/MultipleSelect'
export default {
  data () {
    return {
      selectOptions: [],
      mulSelectLoading: false,
      mulSelecteds: []
    }
  },
  components: {
    MultipleSelect
  },
  methods: {
    mockData () {
      this.mulSelectLoading = true
      setTimeout(() => {
        const options = [
          {label: '选项1', value: '1'},
          {label: '选项2', value: '2'},
          {label: '选项3', value: '3'},
          {label: '选项4', value: '4'},
          {label: '选项5', value: '5'},
          {label: '选项6', value: '6'},
          {label: '选项7', value: '7'},
          {label: '选项8', value: '8'}
        ]
        this.selectOptions = options
        this.mulSelectLoading = false
        this.mulSelecteds = ['2', '4']
      }, 1500)
    }
  },
  mounted () {
    this.mockData()
  }
}
</script>
<style>
.text {
  font-size: 14px;
}

.item {
  padding: 18px 0;
}

.box-card {
  max-height: 400px;
  line-height: 20px;
}
</style>
 类似资料: