木灵鱼儿
阅读:2852
keep-alive 滚动条位置不还原的问题
我想来想去,可能是布局的问题,或者是过渡动画导致的,元素的scroll无法记住。
我尝试给html,body,和最外围的父元素隐藏滚动条,然后只给内容的容器元素设置滚动条,结果切换的时候还是无法记住。
实在没辙,只能用点强迫办法了,就是在路由出去之前记住当前容器的滚动条高度,然后进入的时候延迟一点点时间,再恢复,为什么要延迟呢,这个主要是因为动画的问题。
在需要记住滚动条高度的路由页面使用路由守卫:
//离开之前保存scrollTop
beforeRouteLeave(to, from, next) {
//保存滚动条元素div的scrollTop值
this.scrollY = document.querySelector('.container').scrollTop
next();
}
获取到当前页面的容器,然后获取容器的高度,保存在data的scrollY 中,
进入路由时
beforeRouteEnter(to, from, next) {
next(vm => { // vm = this
document.querySelector('.container').scrollTop = vm.scrollY
})
},
通过next里面的vm来获取当前页面的this,然后来设置容器的高度。
然后就简单了,我们可以给所有的路由页面,需要记录高度的容器设置一个class为container
,然后方法都是一样的了。
基本的做法就是这样,但是我发现使用了过渡动画后,这效果并不会有效,最后我根据我自己的项目的过渡动画时间做了300ms的延迟,然后就可以了
beforeRouteEnter(to, from, next) {
next(vm => { // vm = this
setTimeout(() => {
document.querySelector('.container').scrollTop = vm.scrollY
}, 300);
})
},
优化
这样写的话,很多的东西都重复了,比如变量scrollY,相同的方法,所以,我们可以使用mixins来减少代码书写,然后将方法都封装到methods里面,使用的时候调用就行了。
并且调用的methods的时候,在进入路由的时候,使用vm.xxx()运行的xxx方法时,是可以在这个方法里面使用this来访问上下文的。这一点非常好。
我自己的封装
mixins
export default {
data() {
return {
scrollY: null,
scrollContainer: null
}
},
methods: {
saveScrollY(container) {
this.scrollY = container.scrollTop;
this.scrollContainer = container;
},
restoreScrollY(that) {
if (that.scrollY && that.scrollContainer) {
//300是用于动画延时,不然scroll动不了
setTimeout(() => {
that.scrollContainer.scrollTop = that.scrollY;
}, 300);
}
}
}
}
vue页面调用
<script>
import scrollY from "@/mixins/scrollY";
export default {
mixins: [scrollY],
//离开之前保存scrollTop
beforeRouteLeave(to, from, next) {
//保存滚动条元素div的scrollTop值
this.saveScrollY(this.$refs.homeContainer);
next();
},
//回来的时候恢复滚动
beforeRouteEnter(to, from, next) {
next(vm => {
vm.restoreScrollY(vm);
});
}
};
</script>
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
vue keep-alive导致再次进入父路由时不会自动切换到默认的子路由页面
最近写项目遇到一个问题,很头疼,几天了,问了好些大佬,都没有找到问题的解决方案,但是,最后还是被我找到了,可喜可贺...问题有一个home页,home页里面有router-link元素进行子路由切换,为了减少资源损耗,所以直接使用了keep-alive进行路由页缓存,假设有三个子路由abc,a路由页面有两个子路由a-1和a-2,默认是a-1显示。当我们进入到a路由是,默认显示a-1,然后我们切换到a-2,然后路由push返回到home页,再次进入到a页面时,你会发现,a路由此时显示的a-2而不是a-1,但浏览器地址是a-1的地址,此时,我们可能没办法切换到a-1了。问题图为什么主要因为k...

vue 使用了keep-alive导致下一个路由页面滚动条位置和当前页面相同
keep-alive之前也用的比较玄学吧,后来发现,keep-alive只能缓存当前级页面,也就是说:如果keep-alive缓存了A和B这些同级的路由页面或者组件,那是没问题的,但是如果A页面下还有子级路由或者子组件切换,由于嵌套太深,一般是缓存不到的,所以又需要使用一次keep-alive。但是在使用keep-alive的时候遇到一个问题啊,这个问题很烦。虽然keep-alive缓存后,页面的滚动条位置也会相对应的缓存到,但是,正因为这个位置问题,导致A页面如果滚动了,在进入他的子路由页面的时候,子路由页面的滚动条位置会和A页面保持一致,这就很头疼了。找了半天发现一个绝妙的方式:me...
vue keep-alive 白名单(include)和黑名单(exclude)
keep-alive作为vue的缓存标签,有时候也会遇到一些问题,比如,某些页面我们不想缓存,以前的办法基本都是使用一个v-if然后判断路由的meta标签里面属性设置。但现在不一样了,以前的那种方法并不适合现在了,因为keep-alive自带了黑名单和白名单,在白名单中的路由或者组件将会缓存,黑名单中的则不会缓存。例子 <keep-alive include="a,b" exclude="c,d"> <router-view/> </keep-alive>多个组件用英文逗号隔开,单个就写...