最近做了很多后台管理系统,其中有一个常见的需求,就是从列表页跳入详情页后,要求浏览器记住列表页之前的搜索条件和页码,使得从详情页返回列表页之后,页面不刷新,和上次的操作保持一致。
于是问题定位到组件缓存上。。。如何操作?
想到了几种方案:
- 使用sessionStorage,可行性没什么问题,但是这种方式有一个弊端就是:当系统列表页面特别多时,每个列表页的筛选条件(form表单)和页码都要进行一次sessionStorage存储,比较麻烦。。。
- 将每个列表的筛选条件和页码存入浏览器地址栏中。。(没试过)
- 使用keep-alive(本文重点介绍keep-alive如何使用
结合router,缓存部分页面
- 使用$route.meta的keepAlive属性:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
需要在router中设置router的元信息meta:
export default new Router({
routes: [
{
path: '/pagea',
name: 'pageA',
component: PageA,
meta: {
keepAlive: false // 不需要缓存
}
},
{
path: '/pageb',
name: 'pageB',
component: PageB,
meta: {
keepAlive: true // 需要被缓存
}
}
]
})
在组件里进行判断,只有从详情页返回时才需要做缓存,其他情况不需要缓存,需要重新发送ajax请求
- 将浏览器上一次进入的页面存入一个全局变量中,方便后面进行判断
// 在全局路由守卫中加入这句
router.beforeEach((to, from, next) => {
window.lastRoute = from.name
})
- 在组件中判断
- 使用<keep-alive>会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在activated阶段获取数据,承担原来created钩子中获取数据的任务。
activated() {
// 上一次访问的路由信息不是详情页时
if (window.lastRoute && window.lastRoute !== 'detail') {
// 初始化页面信息并重新发送ajax请求
this.resetPageInfo()
}
}
注:在缓存的组件里面只有第一次进入组件是才会触发created等生命周期钩子函数,再次进来时只会触发activated 和 deactivated