问题1
当你在某页选择了数据,但是在切换页面后,之前选择的数据被清空了,这个时候,你需要在el-table标签上加上row-key属性以及在type="selection"的el-table-column标签上将reserve-selection置为true,如下图:
这样,你就可以解决上述的问题了,切换页面还能保留之前选择的数据。
问题2(全选)
以下两张图 ,是我设计的一个简易的静态页面,以及其对应的代码
// element-ui table 全选 反选 清空 展示
<template>
<div class="w100 h100 f-dir">
<div class="title">
<span>表格全选/反选/清空</span>
</div>
<div class="content">
<div class="btn">
<el-button type="success" @click="click(1)">全选</el-button>
<el-button type="primary" @click="click(2)">反选</el-button>
<el-button type="warning" @click="click(3)">清空</el-button>
<div class="btn-span">
<span class="ml10"
>已选<span>{{ selectList.length }}条</span></span
>
<span class="ml10"
>总记录<span>{{ total }}条</span></span
>
</div>
</div>
<el-table
:data="tablePage"
ref="table"
@selection-change="handleSelectionChange"
:height="500"
:row-key="row=>row.id"
>
<el-table-column type="selection" width="55" :reserve-selection='true'> </el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="sex" label="性别"></el-table-column>
</el-table>
<el-pagination
style="height: 40px"
class="mt15"
background
layout="prev, pager, next"
:total="total"
:page-size="page_size"
:current-page.sync='page'
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
tableAll: [], //所有的数据
tablePage: [], //某一页的数据
selectList: [], //选中的数据
page: 1,
page_size: 25,
total: 0,
};
},
methods: {
// 页数的切换
handleCurrentChange(page) {
console.log(page);
this.page = page
const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
const endIndex = startIndex + this.page_size; // 计算结束索引位置
this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
},
// 点击表格的选择框
handleSelectionChange(val){
this.selectList = val
},
click(num){
// 全选
if(num === 1){
// this.tablePage.map(item=>this.$refs.table.toggleRowSelection(row,true))
this.tableAll.map(row=>this.$refs.table.toggleRowSelection(row,true))
}else if(num === 2){ //反选
this.tableAll.map(row=>this.$refs.table.toggleRowSelection(row))
}else{ //清空
this.$refs.table.clearSelection()
}
}
},
mounted() {
// 这里模拟获取全部数据
for (let i = 0; i < 488; i++) {
this.tableAll.push({
id: i,
name: `name${i}`,
age: `age${i}`,
sex: (i + Number(new Date().getTime())) % 3 === 0 ? "男" : "女",
});
}
// 设置总条数
this.total = this.tableAll.length;
// 默认加载第一页数据
this.handleCurrentChange(1)
},
};
</script>
<style scoped>
.title {
height: 20%;
font-size: 30px;
text-align: center;
margin-top: 15px;
}
.btn {
display: flex;
}
.btn-span {
display: flex;
justify-content: center;
align-items: center;
}
</style>
在这里,每一页的数据都是通过截取总数据,来进行渲染的(如果拿上面的代码能进行正常的全选、反选以及清空)。
但是在实际的开发中,会遇到每页的数据通过调接口储存在arr1,总数据通过调接口储存在arr2中,arr1和arr2其实是那种完全不一样的数组(即使arr1中的数据看起来是arr2的子集),这样和我以上的截取总数据存在本质上的区别(截取其实也是一种浅拷贝)。
在这种情况下,可以用JSON的方法,对总数据先进行深拷贝在截取,用来模拟调接口获取的数据
handleCurrentChange(page) {
console.log(page);
this.page = page
const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
const endIndex = startIndex + this.page_size; // 计算结束索引位置
this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
},
这个时候点击全选,会出现以下的情况。
选中的数据数量是没错的,但是当前页的数据并没有被选中,但是在调到其他页在跳回当前页,这个数据就被选中了,这个咋解决呢?
现在没有实现的需求也就是点击全选后,当前页的选中显示没有显示出来,那么可以采取一点曲线救国的方法,如下
this.tablePage.map(row=>this.$refs.table.toggleRowSelection(row,true)) //全选当前页
const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要全选的数据
otherData.map(row=>this.$refs.table.toggleRowSelection(row,true)) //将剩余数据进行全选
这样下来 全选的操作就没有问题了
这样算来,如果采用这样一个曲线救国的方法,之前反选的代码就不能用了,直接上代码
let selectList = JSON.parse(JSON.stringify(this.selectList)) //这里储存的是之前选中的数据 通过下一行代码 会将this.selectList清空 所以得先存起来
this.$refs.table.clearSelection() //这里直接将之前选中的清空,直接拿selectList来判断那些需要选择,那些不选
this.tablePage.forEach(row => this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) // 反选当前页
const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要反选的数据
otherData.map(row=>this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) //将剩余数据进行反选
如上 就彻底解决的全选、反选、清空的操作了。以下是完整的代码
// element-ui table 全选 反选 清空 展示
<template>
<div class="w100 h100 f-dir">
<div class="title">
<span>表格全选/反选/清空</span>
</div>
<div class="content">
<div class="btn">
<el-button type="success" @click="click(1)">全选</el-button>
<el-button type="primary" @click="click(2)">反选</el-button>
<el-button type="warning" @click="click(3)">清空</el-button>
<div class="btn-span">
<span class="ml10"
>已选<span>{{ selectList.length }}条</span></span
>
<span class="ml10"
>总记录<span>{{ total }}条</span></span
>
</div>
</div>
<el-table
:data="tablePage"
ref="table"
@selection-change="handleSelectionChange"
:height="500"
:row-key="row=>row.id"
>
<el-table-column type="selection" width="55" :reserve-selection='true'> </el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="sex" label="性别"></el-table-column>
</el-table>
<el-pagination
style="height: 40px"
class="mt15"
background
layout="prev, pager, next"
:total="total"
:page-size="page_size"
:current-page.sync='page'
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
tableAll: [], //所有的数据
tablePage: [], //某一页的数据
selectList: [], //选中的数据
page: 1,
page_size: 25,
total: 0,
};
},
methods: {
// 页数的切换
handleCurrentChange(page) {
this.page = page
const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
const endIndex = startIndex + this.page_size; // 计算结束索引位置
// this.tablePage = this.tableAll.slice(startIndex,endIndex)
this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
},
// 点击表格的选择框
handleSelectionChange(val){
console.log(1);
this.selectList = val
},
click(num){
// 全选
if(num === 1){
this.tablePage.map(row=>this.$refs.table.toggleRowSelection(row,true)) //全选当前页
const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要全选的数据
otherData.map(row=>this.$refs.table.toggleRowSelection(row,true)) //将剩余数据进行全选
}else if(num === 2){ //反选
let selectList = JSON.parse(JSON.stringify(this.selectList)) //这里储存的是之前选中的数据 通过下一行代码 会将this.selectList清空 所以得先存起来
this.$refs.table.clearSelection() //这里直接将之前选中的清空,直接拿selectList来判断那些需要选择,那些不选
this.tablePage.forEach(row => this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) // 反选当前页
const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要反选的数据
otherData.map(row=>this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) //将剩余数据进行反选
}else{ //清空
this.$refs.table.clearSelection()
}
}
},
mounted() {
// 这里模拟获取全部数据
for (let i = 0; i < 488; i++) {
this.tableAll.push({
id: i,
name: `name${i}`,
age: `age${i}`,
sex: (i + Number(new Date().getTime())) % 3 === 0 ? "男" : "女",
});
}
// 设置总条数
this.total = this.tableAll.length;
// 默认加载第一页数据
this.handleCurrentChange(1)
},
};
</script>
<style scoped>
.title {
height: 20%;
font-size: 30px;
text-align: center;
margin-top: 15px;
}
.btn {
display: flex;
}
.btn-span {
display: flex;
justify-content: center;
align-items: center;
}
</style>
以上仅作为参考,只是用来给大家提供一个思路,如果觉得还阔以,点个赞,谢谢各位。