新指令化管理滚动状态地址https://blog.csdn.net/theoneEmperor/article/details/82669022(欢迎star),滚动条保存以及回退只需要一条指令,让你为所欲为。
最近学了下node,自己用vue和node弄了个项目。在首页跳到详情页,然后从详情页再跳回来的时候,发现总是要刷新页面,这样对用户操作很不友好,意味着用户不能从上次离开的时候开始浏览,体验极差。我就想能不能回退不刷新,并且记录滚动条的位置,进行复原。
用到keep-alive做缓存的情况
于是就利用了官网上的keep-alive,把要缓存的页面包裹起来。可能有写界面不需要缓存,那么可以把状态写在路由里面进行控制,例如:
// router.js
{ path: '/register', name: 'register', component: register, meta: { keepAlive: false } },
// App.vue 动画的实现,就交给大家集思广益了
<transition :name="transitionName" mode="out-in">
<keep-alive>
<router-view class="child-view" v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
</transition>
<transition :name="transitionName" mode="out-in">
<router-view class="child-view" v-if="!$route.meta.keepAlive"></router-view> </transition>
false表示不需要缓存,true表示需要缓存。使用后,发现页面是缓存了,但是滚动条还是个问题。
解决方案:离开之前先把滚动条位置存起来,就是dom的scrollTop,scrollLeft属性,看你的需求来,如果保存有效期只保存到整个vue实例的创建和销毁,也就是app的打开和关闭,可以存进vuex里面,自己写套规则也行。如果向保存久点,丢进localStorage,浏览器数据库等等都行。回来的时候再把它取出来滚动到相应位置就行了。这时候就需要区分滚动条的类型了,分为window全局滚动条和局部滚动条。
created () {
this.$nextTick(() => {
window.scrollTo(x, y); // 全局滚动条
// 局部滚动
dom.scrollTop = x;
dom.scrollLeft = y;
})
}
如果this.$nextTick失效,不能滚动到目标位置,可以试着用setTimeout包裹,不过极大几率会有从0跳动到目标位置一闪的瞬间,解决方案放到下面一起讲。
不用keep-alive
对于分页加载的列表一定要用keep-alive,或者用我最上面推荐的那个插件里面介绍的写法,然后用vuex把数据缓存起来,这样比keep-alive好点。因为如果你遇到还有tab切换的选项卡型多列表共用一个滚动条现象就比较麻烦了。
对于一般的不分页的,如果不用keep-alive,也会存在从0到目标位置的闪动,视觉效果极差,可以做一些平滑处理。可以路由切换时加个极短时间的动画,来完美错过这个跳动的时间。还可以加一些请求时的loading动画,效果最好的是加在初始化请求的axios拦截器里(ps:假设你用的是axios),效果非常好。好的动画插件比如:animate.css等,vue的官网上都有推荐。就用到了官网给出的transition。多个页面,直接用多个transition包裹,名字保持一致就好了,具体代码:
<transition :name="transitionName" mode="out-in">
<router-view class="child-view"></router-view>
</transition>
如果是全局滚动条的话,可以往其函数里传入options来平滑过渡,具体如下:
window.scrollTo({
top: x,
left: y,
behavior: 'smooth'
});
到这里,就差不多解决了。无时不在,欢迎讨论。