有时候会有这种情况。从列表页面进入详情页面,然后点击返回的时候,我们的接口会重新调用,页面也会跑到顶部,这样用户体验是很不好的,每次用户都得从上往下从新翻,下面就给大家介绍如何解决这种问题;
Vue 提供的方法
当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:
注意: 这个功能只在支持 history.pushState 的浏览器中可用。
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
}
})
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
这种方法只有当body或window发生滚动是才会记录页面的滚动距离(个人认为是这样,因为在我的项目中没有使用成功!!!!)
那如果我的页面是有上、中、下三个盒子组成,上下定高,中间可滚动,我现在只想记录中间盒子的滚动距离,要如何去做呢?下面详解
因为涉及到多个组件的切换,所以用vuex来管理这个数值
export default new Vuex.Store({
state: {
scrollH: 0,
},
mutations: {
scrollChange(state, val) {
state.scrollH = val;
},
})
滚动时触发scrollChange函数
that.$store.commit('scrollChange',scrollTopH);
当从详情页面,回到前一页,并想让其保留在之前的位置,可以在想要滚动的页面执行
activated(){
// 等到DOM更新完成之后,然后,执行this.$nextTick,类似于Promise then()
this.$nextTick(() => {
this.$refs.pags.scrollTo(0, this.scrollH);
// this.$refs.pags.scrollTo(0, this.scrollH);
// console.log('你好吗',this.scrollH);
})
},
activated():
activated()在vue对象存活的情况下,进入当前存在activated()函数的页面时,一进入页面就触发;可用于初始化页面数据、keepalive缓存组件后,可执行方法;
deactivated():离开组件时执行;
注意:activated()和deactivated()只有在包裹的时候才有效;
this.$nextTick()
Vue 在更新 DOM 时是异步执行的,为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。
如果你只想让从详情页回来时,保持上次的状态,添加个路由守卫即可
//如果不是从详情页进入,则就使滚动高度为0
beforeRouteLeave (to, from, next){
if(to.name!="Detail"){
this.$store.commit("scrollChange",0)
}
next()
},
注意:
组件内的守卫
-
beforeRouteEnter (to, from, next)
不!能!获取组件实例this
,因为当守卫执行前,组件实例还没被创建 -
beforeRouteUpdate (to, from, next)
在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this`
-
beforeRouteLeave (to, from, next)
导航离开该组件的对应路由时调用,可以访问组件实例 `this`