一文细解如何保存组件的分页状态。
背景
使用element-plus的分页组件搭建页面的时候,经常会出现这样一种情况:分页为列表页,当从列表页点击某一项进入详情页再返回后,发现分页页数会回到默认值第1页,而不是会停留在跳转前所在的分页目录页,为了优化用户的使用体验,则应该保存好这个当前的分页状态。
一、只有分页列表时的实现原理
利用sessionStorage保存分页页数:
查看官网文档,可以看到分页组件有着一些相应的事件:
也就是说,当页码发生变化的时候,会触发此事件,这也就为实现保存分页状态提供了一个思路:可以在每次切换页码的时候利用sessionStorage保存当前的页数,在这里我利用当前路由为键,当前页码为值。
当用户从列表页——>详情页——>列表页,在列表页的mounted生命周期则可以获取当前存在sessionStorage中的页码数值,并赋值给分页组件绑定的页码变量,不过这里还有两个点需要注意:一是在列表页的时候什么时候去获取sessionStorage的值 二是我们的sessionStorage值应该在什么时候清空。先来解释第一个问题:什么时候获取?进入分页列表页有两种情况:1是从详情页返回,2是初次进入列表页;毋庸置疑,第一种情况下才需要获取sessionStorage中的值,第二种情况并不需要获取之歌值。那如何判断是从详情页返回的呢?可以在进入详情页的时候,存储一个seeion,来标识,再返回列表页的时候则可以判断,该session是否存在,存在即去读取这个当前页码的值,反之则不需要读取;接下来再来解决第二个问题:什么时候清空?当我们在离开当前页面的时候,就需要销毁详情页的标识session值,以防止重新进入新的列表页时 直接获取当前的session值,使分页误跳转。
二、代码展示
1.分页组件模板
<ElPagination
background
layout="prev, pager, next"
:total="pagination.total"
:page-size="pagination.pageSize"
:current-page="pagination.currentPage"
:default-current-page="currentPage"
@current-change="pageChange($event)"
>
</ElPagination>
$event就是当前进行跳转的码数。
在mounted生命周期中完成的代码如下:
const getLastPage = () => {
// 当从详情页返回的时候,先获取详情页中存下来的detall标识,在列表页中,把获取到的分页页码重新赋值赋值,用以返回前的页面,保持不变
if (sessionStorage.getItem('changepage-detail') || sessionStorage.getItem('changepage-draft')) {
// 如果有这个就读取缓存里面的数据
currentPage.value = sessionStorage.getItem(route.path) ? Number(sessionStorage.getItem(route.path)) : ref(1);
pagination.params.current_page = currentPage.value;
} else {
currentPage.value = 1;
// 从其他页面第一次进入列表页,清掉缓存里面的数据
pagination.params.current_page = 1;
sessionStorage.removeItem(route.path);
}
};
详情页添加detail标识
sessionStorage.setItem('changepage-detail', 'detail');
卸载时销毁detail标识
onUnmounted(() => {
sessionStorage.removeItem('changepage-detail');
sessionStorage.removeItem('changepage-draft');
});
二、分页列表➕筛选时的实现原理
当页面只由一个分页组件➕列表构成时,sessionStorage完全可以支持保存状态,但是当我们的页面如果有其他组成部分,比如说支持输入框搜索某一列表项时,这个功能就显得比较鸡肋了,进入详情页在返回后,是无法保存筛选后的列表页以及筛选条件的。vue中有着keep-alive组件可以完美的解决此问题。
2.1什么是keep-alive
翻阅官方文档,可以知道keep-alive是vue中一个内置组件,允许我们在多个组件之间动态切换时,有条件地缓存组件实例。对于一个组件来说,当组件实例发生切换时,会触发unmount生命周期,即被卸载。当利用keep-alive包裹住组件之后,组件的生命周期将会发生相应的变化,对于正常的组件来说,它的生命周期如下:
但如果利用keepalive包裹之后,该组件的生命周期就会发生相应的变化:初次进入时在created和mounted之间添加了actived生命周期,再次进入到该组件时只触发actived生命周期。
扩展:keep-alive内部源码