2x5 VueRouter - 进阶 - 滚动行为

1,278 阅读2分钟

VueRouter 基础教程系列 🎉

滚动行为

创建路由器时,可以使用 scrollBehavior 方法来控制路由切换时页面的滚动位置。 例如,滚动到顶部、保持原先的滚动位置、相对元素位置、锚点滚动等。

scrollBehavior 方法接受三个参数,分别是 tofromsavedPosition,其中 savedPosition 只会在popstate 触发的导航时才可用(浏览器后退/前进/forward/back/go 等触发)。

scrollBehavior 方法通过返回值来控制滚动的目标位置:

滚动到顶部

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior(to, from, savedPosition) {
    return { top: 0 }
  }
});

相对元素位置

返回带有 CSS 选择器或 DOM 元素的 el 属性,此时 topleft 将被视为该元素的相对偏移量(页面会滚动到该元素所在的位置)。

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior(to, from, savedPosition) {
    return { 
        //el:document.querySelector('#box'),
        el:'#box',
    }
  }
});

🤔 为什么滚动位置会相对于 lefttop ?很简单,因为现实中的滚动要么是水平滚动,要么就是垂直滚动。

滚动到锚点

利用相对元素位置滚动,我们还可以实现滚动到锚点的行为:

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return { el: to.hash }
    } else {
      return { top: 0 }
    }
  }
})

原生的滚动位置

通过判断是否存在 savedPosition 参数,如果有便返回,这样便可以兼容与浏览器原生相同的滚动效果。

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0, left: 0 }
    }
  }
})

延迟滚动

有时,我们的滚动可能需要等待一些特定的事件发生,例如,数据请求的响应、等待转场动画过渡完成。 对于此种场景,利用发布/订阅模式将是一个非常好的解决方案。

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior() {
    return new Promise((resolve) => {
      const handler = () => resolve({
        top: 100,
        left: 0,
        behavior: 'smooth'
      })
      //绑定自定义事件
      window.addEventListener('scrollBehavior', handler, { once: true });
    })
  }
})

然后在过渡的钩子中触发事件:

{
  onAfterEnter(){
    window.dispatchEvent(new Event('scrollBehavior'))
  }
}

阻止滚动行为

如果返回一个 falsy 的值,或者是一个空对象,那么不会发生滚动。

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
  scrollBehavior() {
    return {}
  }
})

滚动行为效果

VueRotuer 支持与浏览器原生相同的滚动行为效果:

scrollBehavior() {
    return {
        //smooth 平滑滚动。
        behavior:'smooth'
    }
}

支持 behavior 的原生滚动方法有:

  • window.scrollTo({behavior:'smooth'})
  • window.scrollBy({behavior:'smooth'})
  • element.scrollIntoView({behavior:'smooth'})