v-for遍历el-check-group全选功能

v-for遍历el-check-group全选功能

先上图,看看是不是大家想要的效果
在这里插入图片描述

右上角是一个大的全选功能,每一个方框顶部也是一个全选功能。

后端返回的数据格式
在这里插入图片描述
data是个大数组,数组每一项里面还有一个list数组

HTML代码:

<div class="sgf-check-top">
            <p>选择特征:</p>
            <el-checkbox v-model="checkAllList" @change="handleCheckAll" :disabled="startup">全选</el-checkbox>
        </div>
        <div class="sgf-check-content">
            <div class="sgf-check-content-center" v-for="features in featureDataList" :label="features.name"
                :key="features.feature_id">
                <el-checkbox :indeterminate="featureIndeterminate(features)" v-model="features.checkAll"
                    @change="(val) => handleCheckAllChange(val, features)" :disabled="startup">{{ features.name }}
                </el-checkbox>
                <el-collapse v-model="activeNames">
                    <el-checkbox-group v-model="checkedFeatures">
                        <div v-for="feature in features.list" :key="feature.id">
                            <el-checkbox :disabled="startup" class="checkbox-group" :label="feature.name"
                                @change="val => changeItem(val, feature)">
                            </el-checkbox>
                            <el-collapse-item class="collapse-relative" :title="feature.name" :name="feature.name">
                                <div>{{ feature.desc }}</div>
                            </el-collapse-item>
                        </div>
                    </el-checkbox-group>
                </el-collapse>
            </div>
        </div>

获取数据:

featureLists() {
            const that = this
            that.$api.SGFModel.featureList().then((res) => {
                if (res.success == 1) {
                    that.featureDataList = res.data.map(val => ({
                        ...val,
                        checkAll: true, //默认全选
                        allRule: val.list.map(i => i.name)
                    }))
                    this.checkAllList = true
                    that.featureDataList.forEach(el => {
                        el.list.forEach(eq => {
                            this.feature.push(eq.name)  // 获取二维数组所有的name值,在下面需要使用
                        })
                        this.handleCheckAllChange(this.checkAllList, el)   // 默认执行一遍二级全选方法
                        this.featureIndeterminate(el)  // 样式控制
                    })
                }
            })
        }

右上角全选功能:

handleCheckAll(val, index) {
          this.checkAllList = val
          // 当勾选的时候,二级全选的checkAll变成true,否则,checkAll变成false,且el-checkbox-group绑定的v-model值checkedFeatures=[ ]
          if (this.checkAllList) {
              this.featureDataList.forEach(el => {
                  el.checkAll = true   
                  el.list.forEach(eq => {
                      this.checkedFeatures.push(eq.name)
                      eq.is_use = 1   // 根据后端返回数据及需求,is_use=1的时候为选中,is_use=0的时候为未选中。
                  })
              })
          } else {
              this.checkedFeatures = []
              this.featureDataList.forEach(el => {
                  el.checkAll = false
                  el.list.forEach(eq => {
                      eq.is_use = 0
                  })
              })
          }
      }

二级全选功能:

featureIndeterminate(item) {
          return item.allRule.some(v => this.checkedFeatures.indexOf(v) > -1) && !item.allRule.every(v => this.checkedFeatures.indexOf(v) > -1)
      },
handleCheckAllChange(val, features) {
          const filterArr = this.checkedFeatures.filter(v => features.allRule.indexOf(v) === -1);
          this.checkedFeatures = val ? filterArr.concat(features.allRule) : filterArr  // 获取所有选中的值
          features.list.forEach(el => {
              el.is_use = val ? 1 : 0
          })
           // 当选中的长度和接口获取的所有二维数组的长度之和相等时,勾选右上角的全选,否则不勾选
          if (val && this.feature.length == this.checkedFeatures.length) {  
              this.checkAllList = true
          } else {
              this.checkAllList = false
          }
      }

二级全选下方的勾选某一个值功能:

changeItem(val, feature) {
            feature.is_use = val ? 1 : 0   // 勾选上,is_use=1 否则 is_use=0
            // 创建一个全局参数changeList ,当取消勾选的时候,将所有取消勾选的数据放进数组中
            if (val) {
                this.changeList = this.changeList.filter(el => {
                    return el.id != feature.id   // 每勾选一个,数组里面就过滤掉一个
                })
            } else {
                this.changeList.push(feature)     // 每取消勾选,数组里面就添加一个
            }
            if (this.changeList.length == 0) {    //当数组长度为0时,也就意味着已经全部勾选上了,因此,勾选右上角的全选
                this.checkAllList = true
            } else {
                this.checkAllList = false   // 否则,只要数组里面有数据,就说明存在为勾选的项,则取消右上角的全选
            }
        }

完整代码:(仅供参考,希望对大家有帮助)

<template>
    <div class="sgf-check-features">
        <div class="sgf-check-top">
            <p>选择特征:</p>
            <el-checkbox v-model="checkAllList" @change="handleCheckAll" :disabled="startup">全选</el-checkbox>
        </div>
        <div class="sgf-check-content">
            <div class="sgf-check-content-center" v-for="features in featureDataList" :label="features.name"
                :key="features.feature_id">
                <el-checkbox :indeterminate="featureIndeterminate(features)" v-model="features.checkAll"
                    @change="(val) => handleCheckAllChange(val, features)" :disabled="startup">{{ features.name }}
                </el-checkbox>
                <el-collapse v-model="activeNames">
                    <el-checkbox-group v-model="checkedFeatures">
                        <div v-for="feature in features.list" :key="feature.id">
                            <el-checkbox :disabled="startup" class="checkbox-group" :label="feature.name"
                                @change="val => changeItem(val, feature)">
                            </el-checkbox>
                            <el-collapse-item class="collapse-relative" :title="feature.name" :name="feature.name">
                                <div>{{ feature.desc }}</div>
                            </el-collapse-item>
                        </div>
                    </el-checkbox-group>
                </el-collapse>
            </div>
        </div>
    </div>
</template>


<script>
export default {
    props: {
        startup: Boolean
    },
    data() {
        return {
            activeNames: ['1'],
            checkAll: [],
            isTrue: false,
            checkedFeatures: [],
            checkAllList: false,
            featureDataList: [],
            feature: [],
            changeList: []
        }
    },
    created() {
        this.featureLists()
    },
    methods: {
        featureLists() {
            const that = this
            that.$api.SGFModel.featureList().then((res) => {
                if (res.success == 1) {
                    that.featureDataList = res.data.map(val => ({
                        ...val,
                        checkAll: true,
                        allRule: val.list.map(i => i.name)
                    }))
                    this.checkAllList = true
                    that.featureDataList.forEach(el => {
                        el.list.forEach(eq => {
                            this.feature.push(eq.name)
                        })
                        this.handleCheckAllChange(this.checkAllList, el)
                        this.featureIndeterminate(el)
                    })
                }
            })
        },
        handleCheckAll(val, index) {
            this.checkAllList = val
            if (this.checkAllList) {
                this.featureDataList.forEach(el => {
                    el.checkAll = true
                    el.list.forEach(eq => {
                        this.checkedFeatures.push(eq.name)
                        eq.is_use = 1
                    })
                })
            } else {
                this.checkedFeatures = []
                this.featureDataList.forEach(el => {
                    el.checkAll = false
                    el.list.forEach(eq => {
                        eq.is_use = 0
                    })
                })
            }
        },
        featureIndeterminate(item) {
            return item.allRule.some(v => this.checkedFeatures.indexOf(v) > -1) && !item.allRule.every(v => this.checkedFeatures.indexOf(v) > -1)
        },
        handleCheckAllChange(val, features) {
            const filterArr = this.checkedFeatures.filter(v => features.allRule.indexOf(v) === -1);
            this.checkedFeatures = val ? filterArr.concat(features.allRule) : filterArr
            features.list.forEach(el => {
                el.is_use = val ? 1 : 0
            })
            if (val && this.feature.length == this.checkedFeatures.length) {
                this.checkAllList = true
            } else {
                this.checkAllList = false
            }
        },
        changeItem(val, feature) {
            feature.is_use = val ? 1 : 0
            if (val) {
                this.changeList = this.changeList.filter(el => {
                    return el.id != feature.id
                })
            } else {
                this.changeList.push(feature)
            }
            if (this.changeList.length == 0) {
                this.checkAllList = true
            } else {
                this.checkAllList = false
            }
        },
    }
}
</script>

<style lang="scss">
.sgf-check-content-center {
    .el-collapse {
        margin-top: 10px;
    }

    .checkbox-group {
        position: relative;
        top: 20px;

        .el-checkbox__input+.el-checkbox__label {
            display: none;
        }
    }

    .collapse-relative {
        position: relative;
        top: -11px;
        left: 20px;
        width: calc(100% - 20px);
    }
}
</style>
<style lang="scss" scoped>
.sgf-check-features {
    padding: 16px;

    .sgf-check-top {
        display: flex;
        justify-content: space-between;

        p {
            font-size: 12px;
            font-weight: 900;
        }
    }

    .sgf-check-content {
        height: 600px;
        display: flex;
        flex-wrap: wrap;
        text-align: left;
        overflow: auto;

        .sgf-check-content-center {
            position: relative;
            width: calc(32% - 32px);
            border: 1px solid #dddddd70;
            margin: 20px 0.5%;
            padding: 16px;
            border-radius: 10px;
            max-height: 300px;
            overflow: auto;
            box-shadow: 1px 2px 2px #dddddd70;
        }
    }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值