先上效果
第一步:html
全选
{{ item.taskName }} 版本{{ radioitem.taskVersion }}(有效监控企业{{ radioitem.companyNum }}家)
方便大家知道遍历的到底是什么数据,我把后端回来的数据展示一下,仅供参考
第二步:CSS(每个需求的样式都不同,提供的样式仅供参考)
.table-title {
width: 100%;
height: 40px;
padding: 10px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
text-align: left;
}
.email-checkbox {
padding: 20px 0 0 20px;
text-align: left;
.el-checkbox {
width: 33.33%;
margin: 10px 0 10px;
}
}
第三步:JS
首先在data中声明必要的变量
data() {
return {
rwradio: [],//单选框组绑定的数据
rwisIndeterminate: false,//控制全选样式
rwcheckAll: false,//全选
checkedRw: [],//当前分页选中的任务
allrwPageChecked: null, // 所有选中的任务
RW: [],//接口返回来的总数组
rwloading: false,//数据未加载完毕时,展示加载中的效果
}
},
接下来就是实现功能啦
功能一:初始化页面的展示
getrwList() {
this.rwloading = true
this.axios.post('地址', 请求参数).then(res => {
this.RW = res.data.data.rows
//单选框组因为是遍历渲染的,所以必须是数组格式,不能是对象或者简单类型
//reduce方法在这里不过多说明,大家自行了解
this.rwradio = this.RW.reduce((ary, item, index) => {
const obj = {}
//初始设置单选框组每个绑定的都为0,单选框绑定的是taskId,所以都是0的话,对应不上,单选框肯定是不会有选中效果的。
obj[item.taskName] = 0
//如果有勾选,一般是查看效果时,进行回显,this.allrwPageChecked是有数据的(数据格式与后端返回数据结构一致,请参考上方),那么此时再把单选框重新赋值对应的taskId。此时可以对应啦,那么单选框就回有选中的效果。
if (this.allrwPageChecked) {
this.allrwPageChecked.forEach(i => {
if (i.taskName == item.taskName) {
obj[i.taskName] = i.versionList[0].taskId
}
})
}
ary.push(obj)
return ary
}, [])
//这里是形成一个复选框绑定的数组,后续的方法会用到
this.taskNameary = this.RW.reduce((ary, item) => {
ary.push(item.taskName)
return ary
}, [])
this.initrwPageChecked(this.taskNameary)
})
this.rwloading = false
},
//value就是在getrwList()方法中传递过来的复选框的数组
initrwPageChecked(value) {
let checked = [];
//筛选已勾选的taskName,并添加到一个空数组中( checked),
if (this.allrwPageChecked) {
value.forEach(item => {
this.allrwPageChecked.forEach(i => {
if (value.includes(i.taskName)) {
checked.push(i.taskName)
}
})
})
}
//Array.from(new Set(checked))是对checked进行去重,并赋值给复选框组所绑定的checkedRw
this.checkedRw = Array.from(new Set(checked))
//以下请查看element-ui的官方网站,都是固定的写法
let checkedCount = this.checkedRw.length
this.rwcheckAll = checkedCount === this.RW.length
this.rwisIndeterminate = checkedCount > 0 && checkedCount < this.RW.length
},
功能二:全选
rwhandleCheckAll(val) {
//val返回的是true/false
//如果全选
if (val) {
//1.checkedRw复选框绑定的值等于初始化页面时获取到的所有(this.taskNameary如果不记得了,请看功能一)
this.checkedRw = this.taskNameary
//2.this.allrwPageChecked代表已选中的,那么它就把初始化页面获取到的所有都添加进去
this.RW.forEach(item => {
this.allrwPageChecked.push(item)
})
//3.对this.allrwPageChecked进行数组复杂类型的去重
let allrwPageCheckedobj = {}
this.allrwPageChecked = this.allrwPageChecked.reduce((ary, item) => {
allrwPageCheckedobj[item.taskName] ? '' : allrwPageCheckedobj[item.taskName] = true && ary.push(item)
return ary
}, [])
//4.rwradio单选框组此时就不能赋值为0了,而是直接赋值(我这里时默认选第一条数据,所以绑定的是versionList[0])
this.rwradio = this.RW.reduce((ary, item, index) => {
const obj = {}
obj[item.taskName] = item.versionList[0].taskId
ary.push(obj)
return ary
}, [])
}
//如果取消全选
else {
//1.checkedRw复选框为空数组
this.checkedRw = [];
//2.this.allrwPageChecked重新赋值为,不包含初始化页面获取到的所有
this.RW.forEach(item => {
this.allrwPageChecked = this.allrwPageChecked.reduce((ary, i) => {
if (i.taskName != item.taskName) {
ary.push(i)
}
return ary
}, [])
});
//3.rwradio单选框组再次全部赋值为0
this.rwradio = this.RW.reduce((ary, item, index) => {
const obj = {}
obj[item.taskName] = 0
ary.push(obj)
return ary
}, [])
}
//4.这个必须加上控制全选按钮的样式
this.rwisIndeterminate = false
},
功能三:复选框组的勾选控制全选按钮
handleCheckedrwChange(value) {
//直接看官方文档
let checkedCount = value.length
this.rwcheckAll = checkedCount === this.RW.length
this.rwisIndeterminate = checkedCount > 0 && checkedCount < this.RW.length
},
功能四:复选框单独选中/取消
//val:是否勾选;rw:复选框的名称;rwobj:单个复选框包含的所有数据
rwhandleSingleCheck(val, rw, rwobj) {
//如果勾选
if (val) {
//1.this.allrwPageChecked代表已勾选的数组,把rwobj添加进去
this.allrwPageChecked.push(rwobj)
//2.this.allrwPageChecked进行去重
let allrwPageCheckedobj = {}
this.allrwPageChecked = this.allrwPageChecked.reduce((ary, item) => {
allrwPageCheckedobj[item.taskName] ? '' : allrwPageCheckedobj[item.taskName] = true && ary.push(item)
return ary
}, [])
//3. this.rwradio单选框组对应的数据赋值为正确的值而非0
this.RW.forEach(item => {
if (item.taskName == rw) {
this.rwradio.forEach(i => {
i[rw] = item.versionList[0].taskId
})
}
})
}
//如果取消勾选
else {
//1.this.allrwPageChecked通过indexOf方法,找到对应的索引值,在通过splice方法,进行删除
this.allrwPageChecked.forEach(item => {
if (item.taskName == rwobj.taskName) {
this.allrwPageChecked.splice(this.allrwPageChecked.indexOf(item), 1)
}
})
//2.this.rwradio单选框组对应的数据再次赋值为0
this.rwradio.forEach(item => {
item[rw] = 0
})
}
},
功能五:单选框的取消切换
//obj:单选框的对象信息;name:单选框对应的多选框的名字,也就是taskname
radiochange(obj, name) {
//1.创建一个this.allrwPageChecked所需要的格式
let a = {
taskName: name,
versionList: [obj]
}
//2.当多选框没有勾选的情况时,也就是直接选中而非进行单选框的切换
if (this.checkedRw.indexOf(name) == -1) {
//2.1直接把a添加到已勾选的数组中,此时this.allrwPageChecked是没有重复项的,不需要去重
this.allrwPageChecked.push(a)
}
//3.当多选框组已经勾选,是单选框组进行切换
else {
//3.1根据indexOf方法(从前往后找,找到就停下来,不再继续查找)找到taskName相等时,item对应的索引
//3.2根据splice方法,对this.allrwPageChecked数组进行替换
this.allrwPageChecked.forEach(item => {
if (item.taskName == name) {
this.allrwPageChecked.splice(this.allrwPageChecked.indexOf(item), 1, a)
}
})
}
//4.针对this.checkedRw多选框组不存在数据进行添加
if (!this.checkedRw.includes(name)) {
this.checkedRw.push(name)
}
//5.控制全选按钮的样式,一定要写
this.rwisIndeterminate = true
},