实现效果:
只需要给el-table添加row-key el-table-column添加:reserve-selection="true"
代码如下:
<el-table :data="tableList" border class="table" ref="recordTable" header-cell-class-name="table-header"
:row-key="getRowKey" @selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
align="center"
>
</el-table-column>
</el-table>
表格上方需单独加全选按钮,可参考下面代码。
<el-checkbox
:indeterminate="indeterminate"
@change="handleCheck"
label="所有商品"
v-model="allCheck">
</el-checkbox>
<el-table :data="tableList" border ref="recordTable"
:row-key="getRowKey" @select="handleSelectRow" @selection-change="handleSelectionChange"
@select-all="handleSelectAll">
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
align="center"
>
</el-table-column>
</el-table>
js
data(){
return:{
multipleSelectionAll: [],//所有选中的数据包含跨页数据
allCheck: false,
indeterminate: false,
tableList: [],//列表数据-请求得到或自定义
total: 0,//得到的列表总数
checkedList: [],//选中列表
uncheckedList: [],//未选中列表
}
},
watch: {
//监听列表,如果为所有全选,翻页时保持状态
tableList: {
handler(value) {
if (this.allCheck) {
if (this.uncheckedList.length === 0) {
this.$nextTick(() => {//这里一定要用$nextTick
value.forEach(row => {
this.$refs.recordTable.toggleRowSelection(row, true)
})
})
} else {
this.$nextTick(() => {
value.forEach(row => {
for (let i = 0; i < this.uncheckedList.length; i++) {
if (row.id === this.uncheckedList[i].id) {
this.$refs.recordTable.toggleRowSelection(row, false)
break
} else {
this.$refs.recordTable.toggleRowSelection(row, true)
}
}
})
})
}
}
},
deep: true
},
//监听未选中的数组
uncheckedList: {
handler(value) {
//1.未选中数组长度和总数相等,取消选中状态,取消样式
if (value.length === this.total) {
this.allCheck = false
this.indeterminate = false
}
//2.未选中数组长度为0,取消样式
if (value.length === 0) {
this.indeterminate = false
}
},
deep: true
},
//监听选中数组
checkedList: {
handler(value) {
//选中数组长度等于总数,代表全部选中,取消样式
if (value.length === this.total) {
this.allCheck = true
this.indeterminate = false
}
}
}
},
methods: {
getRowKey(row) {
return row.id;
},
handleSelectRow(rows, row) { //单行选择
if (this.allCheck) {
// 多选框样式改变,allCheck依然为true,为了保持翻页状态
this.indeterminate = true
// 判断勾选数据行是选中还是取消
let selected = rows.length && rows.indexOf(row) !== -1
let lenFalse = this.uncheckedList.length
if (selected) {
// 选中,从未选中数组中去掉
if (lenFalse !== 0) {//
for (let i = 0; i < lenFalse; i++) {
if (this.uncheckedList[i].id === row.id) {
this.uncheckedList.splice(i, 1)
break
}
}
}
} else {
// 取消,当前取消的行push进去
this.uncheckedList.push(row)
}
} else {
this.checkedList = rows
}
},
handleSelectAll(rows) {
if (this.allCheck) {
this.indeterminate = true
let lenNow = this.tableList.length
// 判断全选本页,是选中还是取消
console.log(this.tableList[0]);
if (rows.indexOf(this.tableList[0]) !== -1) {
//如果选中所有rows存在于tableList,或者判断rows长度不为0 证明是选中状态
//uncheckedList要删除当前页tableList
for (let i = 0; i < lenNow; i++) {
for (let n = 0; n < this.uncheckedList.length; n++) {
if (this.uncheckedList[n].id === this.tableList[i].id) {
this.uncheckedList.splice(n, 1)
}
}
}
} else {
// 取消 如果rows为空,当页是取消状态
for (let j = 0; j < lenNow; j++) {
if (this.uncheckedList.length !== 0) {//如果uncheckedList已经有值
if (this.uncheckedList.indexOf(this.tableList[j]) === -1) {
//就把uncheckedList中没有的当前页tableList,push进去
this.uncheckedList.push(this.tableList[j])
}
} else {//如果为空,直接全部push
this.uncheckedList.push(this.tableList[j])
}
}
}
} else {
this.checkedList = rows
}
},
handleCheck() {
if (this.indeterminate) {//当不为全选样式时,点击变为全选
this.allCheck = true
}
//只要点击了全选所有,这两个数组清空
this.uncheckedList = []
this.checkedList = []
if (this.allCheck) {//全选所有,列表全部选中,包括翻页
this.tableList.forEach(row => {
this.$refs.recordTable.toggleRowSelection(row, true)
})
} else {//取消列表全选状态,包括翻页
this.$refs.recordTable.clearSelection()
}
},
//选中数据
handleSelectionChange(val) {
//选中的数据获取地方
this.multipleSelectionAll = val;
},
}