基于element-ui的el-selection实现全选功能

//组件
<template>
  <el-select multiple collapse-tags v-model='selectedArray' @change='changeSelect' placeholder='请选择' @remove-tag="handleRemoveTag">
    <el-option label='全选' value='all' @click.native='selectAll'></el-option>
    <el-option v-for='(item, index) in options' :key='index' :label='item.name' :value='item.name'></el-option>
  </el-select>
</template>

<script>
export default {
  name:'Home',
  data(){
    return {
      selectedArray:[],
    }
  },
  props:{
    options:{
      type:Array,
      default(){
        return []
      }
    },
    value:{
      type:Array,
      default(){
        return []
      }
    }
  },
  watch:{
    // 默认不需要全选,则关闭监听
    options:{
      handler(){
        this.selectedArray= ['all',...this.options.map(({name})=>name)]
      },
      immediate:true
    }
  },
  methods:{
    // 点击全选选项触发
    selectAll(){
      if(this.selectedArray.length <= this.options.length){
        // 当选择长度小于选项长度,点击全选选项,全选所有选项
        this.selectedArray= ['all',...this.options.map(({name})=>name)]
      }else{
        // 清除所有选项
        this.selectedArray=[]
      }
    },
    // 选项变化的回调
    changeSelect(){
       const isIncludeAll = this.selectedArray.includes('all')
      if(this.selectedArray.length === this.options.length&&!isIncludeAll){
        // 除全选选项以外,其他选项全部选中时,添加全选选项
        this.selectedArray.unshift('all')
      }else if(isIncludeAll){
        // 当全选选中,点其他选项,删除全选选项
        const index = this.selectedArray.indexOf('all')
        if(index!==-1)this.selectedArray.splice(index,1)
      }
    },
    handleRemoveTag(val){
      if(val==='all'){
        this.selectedArray=[]
      }
    }
  }
}
</script>

—使用

<Selection v-model='selection' :options="options"/>

需要根据选中的条件,请求数据的;
用第一种写法,当页面中有多个下拉框,会触发多次请求,

//组件内部
<template>
    <el-select v-model="selectedList" placeholder="请选择" multiple collapse-tags size="mini">
        <el-option label="全部" value="all" @click.native="handleSelectedAll"/>
        <el-option v-for="(item, i) in childOptions" :key="i" :label="item.name" :value="item.id" />
    </el-select>
</template>

<script>
export default {
  name: 'SelectAllTwo',
  props: {
    value: {
      type: Array,
      default() {
        return [];
    }
  },
  childOptions: {
      type: Array,
      default() {
        return [];
      }
    },
    changeSelected:{
      type:Function,
      default() {
        return Promise.resolve();
      }
    }
  },
  data() {
    return {
      selectedList: [],//筛选条件
    };
  },
  watch: {
    selectedList: {
      handler(newValue = [], oldValue = []) {
        const isNewValueAll = newValue.includes('all')
        const isOldValueAll = oldValue.includes('all')
        const newValueLength = newValue.length
        const childOptionsLength = this.childOptions.length
        if((isNewValueAll && !isOldValueAll)){
          // 点击全选 
          console.log(this.selectedList,'第一个if')
          this.selectedList = ['all', ...this.childOptions.map(({ id }) => id)];
          // this.refreshData()

        }else if(!isNewValueAll && isOldValueAll && newValueLength === childOptionsLength){
          // 当所有选项全部点着,再次点击全选,清空所有选项
          console.log(this.selectedList,'第二个if')
          this.selectedList = [];
        }else if(isNewValueAll && isOldValueAll && newValueLength === childOptionsLength){
          // 全选状态下,点击除全选的其他项
          console.log(this.selectedList,'第三个if')
          this.selectedList = newValue.filter((item) => item !== 'all');
          this.refreshData()
        }else if(!isNewValueAll && newValueLength === childOptionsLength){
          // 除all,其他选项被全选的时候触发
          console.log(this.selectedList,'第四个if')
          this.selectedList = ['all', ...this.childOptions.map(({ id }) => id)];
          this.refreshData()
        }else if(!newValue.includes('all') && !oldValue.includes('all')&&newValue.length!==oldValue.length){
          // 未选择all时,选择其他选项时
          console.log(this.selectedList,'第五个if')
          this.refreshData()
        }
    },
  },
    childOptions:{
      handler(){
        // 默认全选状态
        this.selectedAll()
      },
    }
  },
  methods:{
    /* method:处理筛选数据中的all */
    reviseSelection(){
      const index = this.selectedList.indexOf('all')
      let selectedList = [...this.selectedList]
      if(index!==-1){
        selectedList.splice(index,1)
      }
      // 删除all以后,判断如果筛选条件为全选,则返回空筛选条件
      return selectedList.length===this.childOptions.length?[]:selectedList
    },
    /* @method:全选 */
    selectedAll(){
      this.selectedList = ['all',...this.childOptions.map((({ id }) => id))]
    },
    /* @method: 向父组件传递数据,刷新筛选*/
    refreshData(){
      const reviseSelection = this.reviseSelection()
      this.$emit('input', reviseSelection);
      this.changeSelected()
    },
    /* @method:点击全选按钮触发 */
    handleSelectedAll(){
      const isSelectedAll = this.selectedList.includes('all')
      if(isSelectedAll)this.refreshData()
    }
  }
};
</script>

<style scoped></style>

—使用

<SelectionOptions v-model="myAppForm.applyType" :child-options="applyTypes" :changeSelected="handleFormChange" ref="applyType"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值