先看一下结果图:
官方文档:https://element.eleme.cn/#/zh-CN/component/checkbox
其中需要注意的几点:
- 单独选择的时候全选按钮应该变成indeterminate 状态;
- 在已有部分选择时点击全选秩序添加未选择的元素,而非所有;
- 页码切换后应当保留当页选择状态;
<template>
<div class="group">
<div class="box check">
<div class="search">
<el-checkbox class="selectAll" :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
<el-checkbox @change="handleCheckBackChange">反选</el-checkbox>
</div>
<el-form ref="form" label-width="0px" v-loading="loading">
<el-form-item label="">
<el-checkbox-group v-model="checkValue" @change="checkChange">
<el-checkbox v-for="(item, index) in list" :key="index" :label="item.id">{{ item.id }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<!-- 分页 -->
<div class="page">
<el-pagination :current-page="page" :page-sizes="[15, 20, 30, 40]" :page-size="num" layout="total, sizes, prev, pager, next, jumper" :total="total" @current-change="pageChange" @size-change="sizeChange"></el-pagination>
</div>
{{ checkValue }}
</div>
</div>
</template>
<script>
import { list } from '@/api/index' // 引入后端接口
export default {
data() {
return {
list: [],
page: 1,
num: 30,
total: 0,
loading: false,
checkValue: [], // 已经选择的元素
isIndeterminate: false, // 全选按钮indeterminate状态
checkAll: false // 全选按钮是否全选
}
},
mounted() {
this.getList()
},
methods: {
getList: function(search) { // 获取列表数据
if (search) {
this.page = 1
}
this.loading = true
let params = {
page: this.page,
num: this.num
}
list(params).then(res => { // 请求后端接口获取列表数据
this.list = res.data.list
this.total = res.data.total // 总数
this.loading = false
this.checkIsIndeterminate() // 每次请求后获取当前页全选按钮的状态,主要用于页码变化
}).catch(res => {
this.loading = false
})
},
checkIsIndeterminate: function() { // 判断当前页全选按钮的状态
let has = 0 // 记录当前页面已选项的条数
this.list.map(item => {
if (this.checkValue.indexOf(item.id) != -1) {
has++
}
})
if (has > 0) { // 有已选项
if (has == this.list.length) { // 判断是否已经全选
this.isIndeterminate = false
this.checkAll = true
} else {
this.isIndeterminate = true
this.checkAll = false
}
} else { // 无已选项
this.isIndeterminate = false
this.checkAll = false
}
},
checkChange: function(value) { // 多选框的值变化
this.checkIsIndeterminate()
},
handleCheckAllChange(val) { // 全选或全不选
if (val) { // 全选
this.list.map(item => {
if (this.checkValue.indexOf(item.id) == -1) {
this.checkValue.push(item.id)
}
})
} else { // 全不选
this.list.map(item => {
if (this.checkValue.indexOf(item.id) != -1) {
this.checkValue.splice(this.checkValue.indexOf(item.id), 1)
}
})
}
this.isIndeterminate = false
},
handleCheckBackChange() { // 反选
let _this = this
this.list.forEach(item => {
if (_this.checkValue.indexOf(item.id) != -1) { // 去掉已选项
_this.checkValue.splice(_this.checkValue.indexOf(item.id), 1)
} else { // 添加未选项
_this.checkValue.push(item.id)
}
})
console.log(this.checkValue)
this.checkIsIndeterminate()
},
pageChange: function(page) { // 页码发生变化
this.page = page
this.getList()
},
sizeChange: function(num) { // 每页条数发生变化
this.page = 1
this.num = num
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.group{
margin-right: 30px;
.search{
margin-bottom: 20px;
}
.el-checkbox-group{
font-size: 17px;
border-left: 1px solid #DEE2E6;
.el-checkbox {
border-right: 1px solid #DEE2E6;
border-bottom: 1px solid #DEE2E6;
margin-right: 0;
width: 20%;
padding-left: 20px;
line-height: 44px;
color: #666666;
}
.el-checkbox:nth-child(1), .el-checkbox:nth-child(2), .el-checkbox:nth-child(3), .el-checkbox:nth-child(4), .el-checkbox:nth-child(5){
border-top: 1px solid #DEE2E6;
}
}
}
</style>