ElementUI Checkbox 多选框-编程思维

一、概述

因项目需求,需要做一个多选设置。

先来看一下官方的demo

test.vue

<template>
  <div>
    <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
    <div style="margin: 15px 0;"></div>
    <el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
      <el-checkbox v-for="city in cities" :label="city" :key="city">{{city}}</el-checkbox>
    </el-checkbox-group>
  </div>
</template>
<script>
  const cityOptions = ['上海', '北京', '广州', '深圳'];
  export default {
    data() {
      return {
        checkAll: false,
        checkedCities: ['上海', '北京'],
        cities: cityOptions,
        isIndeterminate: true
      };
    },
    methods: {
      handleCheckAllChange(val) {
        this.checkedCities = val ? cityOptions : [];
        this.isIndeterminate = false;
      },
      handleCheckedCitiesChange(value) {
        let checkedCount = value.length;
        this.checkAll = checkedCount === this.cities.length;
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length;
      }
    }
  };
</script>
View Code

 

效果如下:

 

 

indeterminate 属性用以表示 checkbox 的不确定状态,一般用于实现全选的效果。

当indeterminate为true时,会出现减号,表示不是全选。为false,会出现对勾,表示全选。

全选的标签用的是el-checkbox,v-model绑定的值是布尔值。

el-checkbox-group标签中,v-model绑定的值是数组,数组里面就是绑定的label的值。

 

二、项目演示

注意:在官方的demo中,使用的基础数据是:['上海', '北京', '广州', '深圳']

发现没有,它的数据机构很简单,在实际项目中,其实数据会比它复杂一点,比如:

[
    {
      id:1,
      name:'上海',
      checkAll:false,
      isIndeterminate:false,
      checkedCities:[],
      children:[
        {
          parentId:1,
          id:2,
          name:'松江区',
        },
        {
          parentId:1,
          id:3,
          name:'杨浦区区',
        },
      ]
    },
    {
      id:10,
      name:'武汉',
      checkAll:false,
      isIndeterminate:false,
      checkedCities:[],
      children:[
        {
          parentId:10,
          id:11,
          name:'汉阳区',
        },
        {
          parentId:10,
          id:12,
          name:'武昌区',
        },
      ]
    }
  ]
View Code

 

test.vue

<template>
  <div>
    <div class="area-list" style="overflow:hidden" v-for="(item,index) in cities" :label="item.id"
         :key="item.id">
      <el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll"
                   @change="handleCheckAllChange($event,item)">{{item.name}}
      </el-checkbox>
      <el-checkbox-group v-model="item.checkedCities" class="a-row" @change="handleCheckedCitiesChange($event,item)">
        <el-checkbox v-for="(item2,index2) in item.children"
                     :label="item2.id"
                     :key="item2.id">
          <div>{{item2.name}}</div>
        </el-checkbox>
      </el-checkbox-group>
    </div>
    <div>
      当前选择的是:{{option}}
    </div>
  </div>
</template>
<script>
  const cityOptions = [
    {
      id:1,
      name:'上海',
      checkAll:false,
      isIndeterminate:false,
      checkedCities:[],
      children:[
        {
          parentId:1,
          id:2,
          name:'松江区',
        },
        {
          parentId:1,
          id:3,
          name:'杨浦区区',
        },
      ]
    },
    {
      id:10,
      name:'武汉',
      checkAll:false,
      isIndeterminate:false,
      checkedCities:[],
      children:[
        {
          parentId:10,
          id:11,
          name:'汉阳区',
        },
        {
          parentId:10,
          id:12,
          name:'武昌区',
        },
      ]
    }
  ];
  export default {
    data() {
      return {
        checkAll: false,
        checkedCities: [],
        cities: cityOptions,
        isIndeterminate: true,
        option:[],
      };
    },
    methods: {
      // 勾选一级菜单时
      handleCheckAllChange(val,item) {
        // console.log("handleCheckAllChange",val)
        // console.log(item)
        // 判断二级菜单数据不为空
        if(item.children&&item.children.length>0){
          // 如果勾选一级,则checkedCities填充所有二级的id,否则为空数组
          item.checkedCities=val?item.children.map(ele=>ele.id):[]
          // 固定状态为false,操作一级菜单时,只有2种状态,要么勾选,要么不不勾选,没有半选状态
          item.isIndeterminate =false
        }
        this.getOption()
      },
      // 勾选二级菜单时
      handleCheckedCitiesChange(value,item) {
        // 判断二级菜单数据不为空,并且当前选中列表长度等于二级菜单长度
        if(item.children&&item.children.length>0&&value.length==item.children.length){
          // 设置全选为true,设置图标为全选
          item.checkAll=true
          item.isIndeterminate = false
        } // 判断二级菜单数据不为空,并且当前选中列表长度小于二级菜单长度,并且当前选中列表不为空
        else if(item.children&&item.children.length>0&&value.length<item.children.length&&value.length>0){
          // 设置全选为false,设置图标为半选
          item.checkAll=false
          item.isIndeterminate = true
        }
        else{
          item.checkAll=false
          item.isIndeterminate = false
        }
        this.getOption()
      },
      // 获取选择的选项
      getOption(){
        this.option=[]
        for (let val of this.cities) {
          // console.log("val",val)
          // 一级菜单勾选时,则全部勾选二级菜单
          if(val.checkAll){
            this.option.push(val.id)
          }
          // 二级菜单有勾选时
          if(val.checkedCities&&val.checkedCities.length>0){
            // console.log("二级菜单有数据",val.checkedCities)
            // 加入一级菜单
            if(this.option.indexOf(val.id)==-1){
              this.option.push(val.id)
            }
            // 加入二级菜单勾选
            for (let val2 of val.checkedCities) {
              this.option.push(val2)
            }
          }
        }
        return this.option
      },
    }
  };
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  .area-list{
    margin-bottom: 13px;
    .el-checkbox{
      color: #333;
      font-size: 14px;
      width: 80px;
    }
  }
  .a-row{
    display: inline-block;
  }
</style>
View Code

 

效果如下:

 

注意:最左边的是一级菜单,后面的都是二级菜单。当二级菜单,只有要1个选中,那么一级菜单就是半选状态,非全选。

因此,提交表单参数时,也要将一级菜单的id提交过去才行。

 

 

本文参考链接:

https://element.eleme.cn/#/zh-CN/component/checkbox#jin-yong-zhuang-tai

版权声明:本文版权归作者所有,遵循 CC 4.0 BY-SA 许可协议, 转载请注明原文链接
https://www.cnblogs.com/xiao987334176/p/15819073.html

Markdown 直接转换公众号文章,不再为排版花时间-编程思维

上一篇「又一家数据公司被查,爬虫到底做错了什么?」反响强烈,虽然我这是新号,但还是获得了不少公众号的转发,借机也结识了很多业内大佬,在此感谢大家的抬爱! 同时也有不少号主问我的文章排版是用的哪个网站,我的回答是:自己做的网站! 没错,这就是本文的主角 —— 公众号 Markdown 编辑器 这是我基于一位大佬 @Ly

【VUE学习笔记】VUE3入门-编程思维

快速开始 基础 创建 Vue 应用 模板语法 响应式基础 计算属性 类与样式绑定 条件渲染 列表渲染 事件处理 表单输入绑定 生命周期钩子 侦听器 模板 ref 组件基础 深入组件 组件注册 Props 组件事件 透传 attribute 插槽 依赖注入 异步组件 可重用性 可

Blazor和Vue对比学习(基础1.7):传递UI片断,slot和RenderFragment-编程思维

组件开发模式,带来了复用、灵活、性能等优势,但也增加了组件之间数据传递的繁杂。不像传统的页面开发模式,一个ViewModel搞定整个页面数据。 组件之间的数据传递,是学习组件开发,必须要攻克的难关。这个章节,我们将一起学习如何将UI片断传递给子组件。子组件的UI片断,由父组件来提供,子组件接收到后直接渲染,这种场景的使