vue封装带有全选的多选框

​ 基于element-ui的多选框组件(el-checkbox)进行二次封装,将全选的逻辑都封装到组件内部,使用v-model的方式进行数据的绑定,方便使用。

  • 依赖

    element-ui@2.15.11

  • 效果

  • 组件代码

    <template>
      <div>
        <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">全选</el-checkbox>
        <div style="margin: 15px 0;"></div>
        <el-checkbox-group v-model="checkData" @change="handleCheckedChange">
          <!--自定义插槽方式定义多选组-->
          <template v-if="$slots.default">
            <slot></slot>
          </template>
          <!--默认方式,数据格式为{value: '', label: ''}-->
          <template v-else>
            <el-checkbox v-for="(item, index) in options" :key="index" :label="item[value]">{{ item[label] }}</el-checkbox>
          </template>
        </el-checkbox-group>
      </div>
    </template>
    <script>
    
    /** @Description 带全选的多选择控件 */
    export default {
      name: 'AllSelectCheckbox',
      model: {
        prop: 'data',
        event: 'change'
      },
      props: {
        data: {
          type: Array,
          default: () => []
        },
        options: {
          type: Array,
          default: () => []
        },
        value: {
          type: String,
          default: 'value'
        },
        label: {
          type: String,
          default: 'label'
        },
        disabled: {
          type: Boolean,
          default: false
        }
      },
      data() {
        return {
          checkData: [],
          checkAll: false
        }
      },
      computed: {
        /** @Description 自动计算isIndeterminate */
        isIndeterminate() {
          const checkedCount = this.checkData.length
          const isIndeterminate = checkedCount > 0 && checkedCount < this.options.length
    
          return isIndeterminate
        },
        /** @Description 全选择的所有value */
        allOptionsValue() {
          return this.options.map(r => r[this.value])
        }
      },
      watch: {
        data() {
          this.checkData = this.data
        }
      },
      created() {
        this.checkData = this.data
      },
      mounted() {
    
      },
      methods: {
        /** @Description 全选 */
        doSelectAll() {
          this.$emit('change', [...this.allOptionsValue])
        },
        /** @Description 取消全选 */
        undoSelectAll() {
          this.$emit('change', [])
        },
        /** @Description 选择框变化 */
        handleCheckedChange(value) {
          const checkedCount = value.length
          this.checkAll = checkedCount === this.options.length
    
          this.$emit('change', value)
        },
        /** @Description 全选框变化 */
        handleCheckAllChange(val) {
          this.$emit('change', val ? [...this.allOptionsValue] : [])
        }
      }
    }
    
    </script>
    <style lang='css' scoped>
    </style>
    
  • 使用示例

    <template>
      <div>
        <AllSelectCheckbox v-model="checkData" :options="options" value="code" label="name" :disabled="false">
          	<!---可以自定义插槽修改多选框内容---->
            <!-- <el-checkbox v-for="(item,index) in options" :key="index" :label="item.code">{{ item.name }}</el-checkbox> -->
        </AllSelectCheckbox>
      </div>
    </template>
    
    <script>
    import AllSelectCheckbox from '@/components/allSelectCheckbox'
    
    export default {
      components: {
        AllSelectCheckbox
      },
      data() {
        return {
          checkData: ['1'],
          options: [
            { code: '1', name: '男' },
            { code: '2', name: '女' },
            { code: '3', name: '其他' }
          ]
        }
      },
      mounted() {
    
      },
      methods: {
        change(val) {
          console.log(val)
        }
      }
    }
    
    </script>
    <style lang='css' scoped>
    </style>
    
    
posted @ 2023-02-03 13:24  linmt  阅读(344)  评论(0编辑  收藏  举报