Select 组件实现【全选】(基于 Element)

〇、前言

在 Element 中,Select 组件支持单选和多选,但是并没有全选的属性,因此只能通过其事件和属性来实现,本文将实现两个简单的示例。

注意:本文的示例中,通过 leixing1 来兼容多控件共享同一方法。

一、两种实现

1.1 通过添加一个 Checkbox 来操作全选(推荐)

  • 大致思路

在全部选项最上边添加一个 Checkbox 复选框,勾选时自动全选,取消勾选自动取消全部已选中项。

再给 Select 添加一个 Change 事件方法,当选中项等于备选列表长度,则自动勾选 Checkbox,否则取消勾选。

  • 实现效果

 

  • 前端实现代码
<el-select 
  class="select-item uniform-width"
  v-model="formData.leixing1"
  filterable multiple 
  clearable @change="changeSelect($event,'leixing1')"
  placeholder="全部类型(多选)"
>
  <el-checkbox :indeterminate="isIndeterminate_lx" v-model="checked" @change="selectAll('leixing1')" style="padding:5px 0 10px 20px;">全选</el-checkbox>
  <el-option
    v-for="item in leixing1OptionsList"
    :label="item.mingcheng"
    :value="item.bianma"
    :key="item.bianma"
  />
</el-select>
  • js 代码实现
<script>
export default {
  name: "Example",
  data() {
    return {
      isIndeterminate:false,
      isIndeterminate_lx1:false,
      isIndeterminate_lx2:false,
      checked:false,
      checked_lx1:false,
      checked_lx2:false,
      formData:[],
      leixing1OptionsList:[
        {mingcheng:"第1项",bianma:"1"},
        {mingcheng:"第2项",bianma:"2"},
        {mingcheng:"第3项",bianma:"3"},
      ],
      leixing2OptionsList:[],
    };
  },
  methods: {
    changeSelect(val,leixing) {
      let list=[]
      let value=""
      switch (leixing){ // 根据不同的组件对取值进行区分
        case "leixing1":
          list=this.leixing1OptionsList
          this.checked=this.checked_lx1
          break
        case "leixing2":
          list=this.leixing2OptionsList
          this.checked=this.checked_lx2
          break
      }
      if (this.formData[leixing].length==list.length) { // 全选
        this.checked=true
        this.isIndeterminate=false
      } else if (this.formData[leixing].length!=list.length && this.formData[leixing].length>0) {
        this.checked=false
        this.isIndeterminate=true
      }else if(this.formData[leixing].length==0){
        this.isIndeterminate=false
      }
      switch (leixing){
        case "leixing1":
          this.checked_lx1=this.checked
          this.isIndeterminate_lx1=this.isIndeterminate
          break
        case "leixing2":
          this.checked_lx2=this.checked
          this.isIndeterminate_lx2=this.isIndeterminate
          break
      }
    },
    selectAll(leixing) {
      let list=[]
      let value=""
      switch (leixing){ // 根据不同的组件对取值进行区分
        case "leixing1":
          list=this.leixing1OptionsList
          this.checked=this.checked_lx1
          this.isIndeterminate_lx1=false
          value="bianma"  // 具体的取值属性配置
          break
        case "leixing2":
          list=this.leixing2OptionsList
          this.checked=this.checked_lx2
          this.isIndeterminate_lx2=false
          value="key"  // 具体的取值属性配置
          break
      }
      if (this.checked) { // 全选
        list.map((item) => {
          if(!this.formData[leixing].includes(item[value])) // 判断是否已存在
            this.formData[leixing].push(item[value])
        })
      } else { // 取消全选
        this.formData[leixing] = [];
      }
    },
  },
};
</script>

1.2 通过增加一个 Option 选项‘全选’来实现

  • 大致思路

手动增加 Select 的第一个选项‘全选’,通过这个选项的事件,来操作是否全选。

再通过列表的长度和已选中的选项进行比较,相等就自动勾选‘全选’,否则就取消勾选。

注意:Select 组件的值会包含‘全选’这个值,需要在后端进行过滤。

  • 实现效果

  • 前端控件代码
<el-select 
  class="select-item uniform-width"
  v-model="formData.leixing1"
  filterable multiple 
  clearable @change="changeSelect($event,'leixing1')"
  placeholder="全部类型(多选)"
>
  <el-option label='全选' value='全选' @click.native="selectAll('leixing1')" v-if="leixing1OptionsList.length"></el-option>
  <el-option
    v-for="item in leixing1OptionsList"
    :label="item.mingcheng"
    :value="item.bianma"
    :key="item.bianma"
  />
</el-select>
  • js 代码实现及解释
<script>
export default {
  name: "Example",
  data() {
    return {
      formData:[],
      leixing1OptionsList:[
        {mingcheng:"第1项",bianma:"1"},
        {mingcheng:"第2项",bianma:"2"},
        {mingcheng:"第3项",bianma:"3"},
      ],
      leixing2OptionsList:[],
    };
  },
  methods: {
    changeSelect(val,leixing) {
      let list=[]
      let value=""
      switch (leixing){ // 根据不同的组件对取值进行区分
        case "leixing1":
          list=this.leixing1OptionsList
          break
        case "leixing2":
          list=this.leixing2OptionsList
          break
      }
      if (!val.includes('全选') && val.length === list.length) { // 手动选择全部选项后,自动选中‘全选’
        this.formData[leixing].unshift('全选')
      } else if (val.includes('全选') && (val.length - 1) < list.length) { // 取消选中任一项,同时取消‘全选’
        this.formData[leixing] = this.formData[leixing].filter((item) => { return item !== '全选'})
      }
    },
    selectAll(leixing) {
      let list=[]
      let value=""
      switch (leixing){ // 根据不同的组件对取值进行区分
        case "leixing1":
          list=this.leixing1OptionsList
          value="bianma"  // 具体的取值属性配置
          break
        case "leixing2":
          list=this.leixing2OptionsList
          value="key"  // 具体的取值属性配置
          break
      }
      if (this.formData[leixing]!=undefined && this.formData[leixing].length < list.length) { // 全选
        this.formData[leixing] = ['全选'] // 默认选中‘全选’这一项
        list.map((item) => { // 将全部选项加入值列表
          if(!this.formData[leixing].includes(item[value])) // 判断是否已存在
            this.formData[leixing].push(item[value])
        })
      } else { // 取消全选
        this.formData[leixing] = [];
      }
    },
  },
};
</script>
posted @ 2025-06-12 20:25  橙子家  阅读(909)  评论(1)    收藏  举报