问题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>
复制
以上仅作为参考,只是用来给大家提供一个思路,如果觉得还阔以,点个赞,谢谢各位。