@[TOC]keep alive 实现组件切换缓存页面,并记住当前的滚动位置
场景
home组件下动态渲染文章列表组件,
<!-- 文章列表 -->
<article-list ref="alist" :channel="channel"></article-list>
点击进入当前文章,返回至首页页面刷新
keep alive
官网介绍: 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 要求同时只有一个子元素被渲染。
Router中配置meta
{
path: '',
name: 'home',
meta: {
keepAlive: true //需要被缓存
},
component: () => import('@/views/home')
},
{
path: '/video',
name: 'video',
component: () => import('@/views/video'),
meta: {
keepAlive: false //不需要被缓存
},
},
路由出口
要求同时只有一个子元素被渲染。
app.vue
此时页面已经不会刷新了。还需要记住页面的滚动的位置
记住页面的滚动位置
在滚动的组件 article-list中 添加组件内的守卫 这里的this.active 为当前组件频道的索引项
// 导航离开该组件的对应路由时调用
beforeRouteLeave(to, from, next) {
// console.log(this.$refs.alist);当前组件的实例对象
// console.log(this.$refs.alist[this.active].$el);获取当前的组件实例的dom元素
// console.log(this.$refs.alist[this.active].$el.scrollTop);可以获取当前组件实例dom元素的滚动位置
// 给当前的组件实例绑定属性scrollY, 值为当前组件的滚动的位置 this可以访问当前组件
this.scrollY = this.$refs.alist[this.active].$el.scrollTop;
next(); //守卫需要释放
},
// beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建
beforeRouteEnter(to, from, next) {
next((vm) => {
//console.log(vm); //获取组件的实例
// 判断当前引用是否存在,存在则需要记住当前的位置,页面进入时不需要记住当前的位置
if (vm.$refs.alist) {
// 反过来执行一遍,被实例中存的滚动的距离赋值给当前的实例对象的dom元素的scrollYop,记住滚动的位置
vm.$refs.alist[vm.active].$el.scrollTop = vm.scrollY;
}
}); //守卫需要释放
}