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>