首先说一下我们出现的问题:
1、在初始化el-table表格和el-pagination分页,确保能将数据正常渲染出来后,分页功能页也没问题
2、然后我们进行全选和单选的操作,再点击分页进行切换,发现选中状态消失了...
3、为啥呢?
4、主要是因为默认情况下,在进行分页切换时不会保留之前页选中的状态。这是因为分页切换通常会重新加载新页的数据,从而导致之前页中的数据和选中状态都被清除了。
下面说下我们的解决思路:
1、首先我们需要把我们勾选的状态准确的保存下来
2、分页切换的时候会触发数据的加载,这时我们就需要去除之前存储的勾选状态
3、通过过滤筛选来将已勾选的状态回显到我们的el-table列表中
4、具体实现如下
第一节:代码部分,可直接创建新组件直接引用
部分关键变量和方法解析:
//mockjs为第三放插件,npm i mockjs 安装 ,用于前端生成随机数据时使用,对应下面getlist方法
import Mock from 'mockjs'
//存储的勾选状态
selectsdata:[]
//模拟接口,请求数据的方法
getlist() {
return Mock.mock({ 'list|11-20': [{ 'name': '@cname', 'age|15-25': 0, 'city': '@city' }] }).list;
}
//el-table 回显的方法: 第一个参数回显行、第二个参数bool是否选中
this.$refs.TabsRef.toggleRowSelection(dom,true)
全部代码:
<template>
<div>
<div style="display: flex;">
<div style="width: 60vw;">
<el-table
ref="TabsRef"
:data="currentPageData"
border
style="width: 100%;height: 600px;overflow: auto;"
@select="selects"
@select-all="selects"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="100">
</el-table-column>
<el-table-column
prop="age"
label="年龄"
width="100">
</el-table-column>
<el-table-column
prop="city"
label="地址"
width="200">
</el-table-column>
</el-table>
</div>
<div>
<div>已选:</div>
<span v-for="item in selectsdata">{{ `姓名:${item.name}` }}<br></span>
</div>
</div>
<el-pagination
background
:hide-on-single-page="value"
small
:page-size="pageSize"
layout="prev, pager, next"
:total="arrs.length"
@current-change="handleCurrentChange">
</el-pagination>
</div>
</template>
<script>
//mockjs npm安装 npm i mockjs
import Mock from 'mockjs';
export default {
data() {
return {
arrs: [],
currentPageData: [],
value: false,
pageSize: 10,
currentPage: 1,
selectsdata:[]
};
},
methods: {
getlist() {
return Mock.mock({ 'list|11-20': [{ 'name': '@cname', 'age|15-25': 0, 'city': '@city' }] }).list;
},
//分页点击触发的
handleCurrentChange(page) {
this.currentPage = page;
this.updateCurrentPageData();
//这边要把回显的回显上去
console.log('点击了分页,这个等会要回显,下面是回显的数据,看下对不对');
console.log(this.selectsdata);
if (this.$refs.TabsRef) {
this.currentPageData.forEach((item,index)=>{
// 当前页面的根据这个数组来回显 ,,this.selectsdata
if (this.selectsdata.length>0) {
//有回显的数据
let dom = this.selectsdata.find(items=>{
return items == item
})
if (dom) {
this.$nextTick(()=>{
this.$refs.TabsRef.toggleRowSelection(dom,true)
})
}
}
})
}
},
//这个方法类似🐟请求接口数据
updateCurrentPageData() {
const startIndex = (this.currentPage - 1) * this.pageSize;
const endIndex = startIndex + this.pageSize;
this.currentPageData = this.arrs.slice(startIndex, endIndex); //显示分页对应的
},
selects(selection, row) {
if (this.selectsdata.length === 0) {
console.log('第一次进来,没选,获取全不选的时候触发');
this.selectsdata = selection;
} else {
if (this.selectsdata.length>0 &&!row) {
console.log('点击全选/全不选',selection.length,this.selectsdata);
// 然后修改 回显数据
// this.currentPageData 是所有的数据
if (selection.length>0) {
//全选了
console.log('全选');
this.currentPageData.forEach(item=>{
let find = this.selectsdata.find(selectedItem=>{
return selectedItem.name == item.name
})
if (!find) {
this.selectsdata.push(item)
}
})
}else{
console.log('全不选');
// 仅保留当前页数据中未选中的行
this.selectsdata = this.selectsdata.filter(item => {
// 检查当前行是否存在于当前页数据中
let find = this.currentPageData.find(pageItem => pageItem.name === item.name);
// 如果不存在,则保留该行
return !find;
});
}
return
}else{
console.log('单选');
// 点击的时候有就删,没有就加
const doms = this.selectsdata.find(item => item.name === row.name);
// 如果点击的行已经存在于 selectsdata 中,则将其删除
if (doms) {
this.selectsdata = this.selectsdata.filter(item => item.name !== row.name);
} else {
// 如果点击的行不存在于 selectsdata 中,则将其添加到 selectsdata 中
this.selectsdata.push(row);
}
}
}
}
},
created() {
console.log('N组件');
//这个arrs是所有的数据
this.arrs = this.getlist();
this.updateCurrentPageData();
}
};
</script>
<style>
/* 这里可以添加样式 */
</style>
注意:
代码不过多讲解了,主要看注释理解,几个地方用了判断都是为了区分不同的情况,比如
selection参数是选中的行的数组
row 只有在行内勾选的时候才会有的参数-用来判断是否全选
//全选和单选同的都是同一个方法,所以得区分开他们
//这里是判断是不是第一次选,如果勾选的没状态,就等于第一次选的 selection
if (this.selectsdata.length === 0) {
console.log('第一次进来,没选,获取全不选的时候触发');
this.selectsdata = selection;
} else {
//通过!row来区分是全选还是全部选
if (this.selectsdata.length>0 &&!row) {
//全选内部通过全选的长度,要么为全部选==0 ,要么全选> 0
if (selection.length>0) {
}
else{
}
}else{
}
}
第二节:功能展示部分
初始化:
选中部分的行,右侧可以看到选中的行,为了让大家看到更加直观
第一页:
第二页:
此时我们分别在第一页和第二页各选中了2名,共4名,右侧可见,此时回到第一页查看回显效果
回显依然存在,接下来看全选/全不选
第二页全选,第一页去除两个,右边是对应的数据,后面操作就可以直接拿右侧数据了,OK
第三节:其他相关知识分享
1、一键展开关闭
【前端】- 在使用Element UI 的el-tree组件时,从底层去研究如何去实现一键展开/关闭【tree节点】的功能_el-tree 关闭展开-CSDN博客
2、vite + vue3项目的搭建
使用vite创建vue3项目 + 配置路由 + 配置pinia_vue3安装路由-CSDN博客
3、vite + vite 修改默认启动端口
【功能:vue3 + vite 修改默认启动端口】 - 以及相关配置详细解答,刚学习的小伙伴强烈推荐_vite设置端口-CSDN博客
祝 大 家 开 心 敲 代 码 、远 离 bug