从列表页 ------> 详情页, 再从详情页 -----> 列表页 ,要保存上次已经加载的数据和自动还原上次的浏览位置
1. 缓存组件,vue2中提供了keep-alive。首先在我们的app.vue中定义keep-alive:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
2. 下面在router.js即我们的路由文件中,定义meta信息
// news 是列表页
{
path: '/news ',
name: 'news ',
component: resolve => require(['@/view/news'], resolve),
meta: {
keepAlive: true // 通过此字段判断是否需要缓存当前组件
}
},
这里采用路由懒加载,也可以使用 import 来导入,无关紧要,接着看下面
2.缓存数据的实现
简单了解一下缓存相关的vue钩子函数。
设置了keepAlive缓存的组件:
第一次进入:beforeRouterEnter > created > … > activated->…->deactivated 后续进入时:beforeRouterEnter > activated > deactivated
可以看出,只有第一次进入该组件时,才会走created钩子,而需要缓存的组件中activated是每次都会走的钩子函数。所以,我们要在这个钩子里面去判断,当前组件是需要使用缓存的数据还是重新刷新获取数据.
3. 页面滚动位置的问题
我们知道,在vue这种单页应用中,如果你在a页面滚动了一段距离后,此时前往b页面后,b页面也会停留在a页面的滚动位置。这个问题的解决,我们可以利用router本身提供的功能来解决:
routes: [
{
path: '/detail',
name: 'Detail',
component: resolve => require(['@/view/detail'], resolve)
}
],
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
if (from.meta.keepAlive) {
from.meta.savedPosition = document.body.scrollTop;
}
return { x: 0, y: to.meta.savedPosition || 0 }
}
}
scrollBehavior
是路由提供的基础功能,这段函数写的是:
- 如果通过浏览器自带的前进后退按钮切换的路由,那么会自动使用浏览默认的回滚上次页面的浏览位置。
2.如果是通过vue路由进行的页面切换。例如a前往b,首先判断a是不是通过keep-alive缓存的组件,如果是,则在a路由的meta中添加一个savedPosition字段,并且值为a的滚动位置。最后return的是页面需要回滚的位置。如此一来,如果打开一个页面,该页面的组件路由中meta.savedPosition为undefined的话,则页面滚动到(0,0)的位置,这样解决了问题1。那么如果打开一个页面,它的路由的meta.savedPosition有值的话,则滚动到上次浏览的位置,因为meta.savedPosition保存的就是上次浏览的位置。