参考的原blog链接:vue中使用Checkbox 多选框循环遍历_vue循环列表按钮checkbox-CSDN博客
最终效果图:
html部分:
<el-form-item
class="hy-cloud-export-container"
v-for="(item, index) in exportItemsList"
:key="index">
<div class="export-item-tag"><el-tag size="mini">{{item.label}}</el-tag></div>
<el-checkbox
@change="handleCheckAllChange($event, item)"
:indeterminate="itemIndeterminate(item)"
v-model="item.checkAll">
全选
</el-checkbox>
<el-checkbox-group
class="hy-cloud-export-item"
v-model="checkedData"
@change="handleCheckedExportItemsChange()">
<el-checkbox v-for="items in item.child" :label="items" :key="items.field"
:checked="items.checked">
{{items.label}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
js部分
// data中
checkedData: [], //选择多选框时选中的值
exportItemsList: [ // 所有导出数据
{
label: "用户基础信息",
child: [
{
field: "userId", // field就是后端需要的字段
label: "用户账号", // 页面上显示的checkbox的名称
checked: true // 控制当前checkbox是否被选中,在这里设置为true一开始就会默认勾选,设置为false则不会勾选
},
{
field: "userName",
label: "姓名",
checked: true
}
]
},
{
label: "用户身份信息",
child: [
{
field: "certificateType",
label: "证件类型",
checked: false
},
{
field: "certificateNo",
label: "证件号码",
checked: true
}
]
},
{
label: "用户订购套餐",
child: [
{
field: "wireless",
label: "无线套餐",
checked: true
},
{
field: "wired",
label: "有线套餐",
checked: true
},
{
field: "mixed",
label: "混合套餐",
checked: false
}
]
},
{
label: "用户绑定宽带",
child: [
{
field: "broadband",
label: "运营商对接配置和用户宽带账号",
checked: true
},
{
field: "operatorUserPassword",
label: "用户宽带密码",
checked: true
}
]
}
]
// methods中
// 是否全选
itemIndeterminate (item) {
this.handleCheckedExportItemsChange()
return (
item.child.some((v) => this.checkedData.indexOf(v) > -1) &&
!item.child.every((v) => this.checkedData.indexOf(v) > -1)
)
},
// 全选按钮绑定值发生变化时触发的事件
handleCheckAllChange (val, item) {
const filterArr = this.checkedData.filter((v) => item.child.indexOf(v) == -1)
this.checkedData = val ? filterArr.concat(item.child) : filterArr
},
// 导出字段item绑定值发生变化时触发的事件
handleCheckedExportItemsChange () {
this.exportItemsList.forEach((item) => {
item.checkAll = true
item.child.forEach((v) => {
if (!this.checkedData.includes(v)) {
item.checkAll = false
}
})
})
},
我这边是在dialog中展示的checkbox字段,为了保证dialog关闭再次点击,默认勾选的checkbox不变,代码如下
// 关闭导出dialog
closeExportDialog () {
this.$refs['approveForm'].resetFields() // approveForm是我使用的表单 大家根据自身需求修改
this.exportDialogVisible = false // exportDialogVisible控制dialog 大家根据自身需求修改
// 1、导出对话框关闭 checkedData是之前对话框里被选中的字段集合
// 2、为了恢复默认选项 需要从exportItemsList中重新筛选出checked为true的对象集合
// 3、注意 checkedData的形式为 [{field:'xx',label:'xx',checked:true},{field:'xx',label:'xx',checked:true}]
this.checkedData = [] // checkData需要清空,要不然上一次的会保留,叠加到这次
this.exportItemsList.forEach(item => {
item.child.forEach(v => {
if (v.checked) this.checkedData.push(v)
})
})
console.log('取消this.checkedData', this.checkedData)
},
从checkData中整理出后端需要的字段形式
submitExport () {
let field = []
this.checkedData.forEach(item => {
field.push(item.field)
})
console.log('field', field) // 这就是后端要的
}
遇到问题:
.比如,当用户基础信息的每项都单个勾选了,但是全选没有显示√,必须要再点击一下其他项,才会有√
.通过console.log定位发现是checkAll的值获取延迟了,选中了用户基础信息最后一个未选项时,checkAll还没有变为false
.所以要在itemIndeterminate里面调用handleCheckedExportItemsChange方法同步完checkAll值之后再判断
附:
isIndeterminate(Indeterminate绑定的值) | checkAll(全选v-model绑定的值) | |
true | true | -(半选) |
false | true | √(全选) |
false | false | 空 |