1.效果展示
实现多组数据分组展示并实现勾选功能,使用的是element-ui的checkbox-group组件实现的。
项目中实现效果:
这个组件使用起来真的要注意踩坑,仔细阅读理解官网给的这段介绍,后面写代码都会涉及到。
2.代码实现
html代码
<ul class="menu-sub">
<li v-for="(item,index) in infoArray"
:key="index">
<el-checkbox
@change="(val) => handleCheckAll(val, item)" //全选按钮触发方法
:indeterminate="itemIndeterminate(item)" //是否全选
v-model="item.flag" //v-model绑定,布尔值决定勾选状态
>{{ item.poolName }}</el-checkbox
>
<el-checkbox-group //group中选中数据为数据,且对应
label值,显示勾选状态
v-model="selectedData"
@change="handleChanges(item)"
style="padding-left: 30px;"
>
<el-checkbox
style="width: 230px;"
v-for="items in item.infoList"
:key="items.infoId"
:label="items.infoId" //注意label的绑定值,即取值
>{{ items.infoName }}</el-checkbox
>
</el-checkbox-group>
</li>
</ul>
js代码
selectedList:[], //选中数据(数组)
infoArray:[ //后端返回数据格式(多级)
// {
// poolName:1,
// infoList:[{
// infoId:14324,
// infoName:ces
// }]
// }
],
init(){
listAllCard().then(res=>{
this.cardList=res.data
})
listAllInfo().then(res=>{
// 添加是否全选标识
this.infoArray=(res.data).map((v)=>({
...v,flag:false
}))
})
},
// 全选
handleCheckAll(val,item){
// 过滤掉没有选中的数据,item.child中不包含v时返回-1
const next=item.infoList.map(item=>item.infoId)
const filterArr = this.selectedData.filter(
(v) => next.indexOf(v) == -1
);
this.selectedData= val ? filterArr.concat(next) : filterArr;
},
itemIndeterminate(item) {
const infoLists=item.infoList.map(ite=>ite.infoId)
return (
infoLists.some((v) => this.selectedData.indexOf(v) > -1) &&
!infoLists.every((v) => this.selectedData.indexOf(v) > -1)
);
},
// 勾选变化方法
handleChanges(val){
const infoLists=val.infoList.map(ite=>ite.infoId)
infoLists.every((v) => {
if (this.selectedData.indexOf(v)>-1) {
val.flag = true;
}else{
val.flag=false
}
});
},
handleAdd(row){
this.reset();
this.form.cardId=row.cardId
this.form.templateId=row.templateId
this.postData.templateId=row.templateId
this.cardList.forEach(element => {
if(element.cardId==row.cardId){
this.cardName=element.cardName
}
});
this.templateName=row.templateName
// 回显
this.selectedData=[]
getList(row.templateId).then(res=>{
res.data.forEach(element => {
this.selectedData.push(element.infoId)
// 判断是否全选(放在this.selectedData数据获取完成后,异步请求下数据如果还未存入会导致读取不到,一开始了放在外层,导致回显失败)
this.infoArray.forEach((item,index)=>{
this.tempList[index]=item.infoList.map(ite=>ite.infoId)
this.tempList[index].some((v) => {
if (this.selectedData.indexOf(v)==-1) {
item.flag = false;
}else{
item.flag=true
}
});
})
});
})
this.open = true;
this.title = "设置卡申请模版申请信息";
},
3.总结
1.因为官网给出的checkbox group绑定的数据格式是数组,而在项目中接收的数据通常是对象数组,我这里label绑定的是数组中对象的id属性,点击获取的是id的数组,在最后提交数据时需要做处理。
2.一开始也尝试了label绑定整个对象,这样获取到的直接便是最终需要的对象数组,展示和添加是可以实现的,但是回显遇到了问题,在网上看是回显的数据格式要与选中的数组中对象的格式一致,尝试了没有效果,后面再研究一下。
3.在网上看到了一种方法,使用JSON.stringify()使label绑定对象转换的字符串,还没有尝试是否可行,先记录一下。
<el-checkbox-group v-model="form.userClaims">
<el-form-item v-for="item in items" :key="item.id">
<el-checkbox
:label="JSON.stringify({ id: item.id, type: item.name })"
>{{ item.name }}</el-checkbox
>
</el-form-item>
</el-checkbox-group>