跳至内容

滚动行为

在使用客户端路由时,我们可能希望在导航到新路由时滚动到顶部,或者像真正的页面重新加载一样保留历史记录条目的滚动位置。Vue Router 允许你实现这些,甚至更好,允许你完全自定义路由导航时的滚动行为。

注意:此功能仅在浏览器支持 history.pushState 时有效。

在创建路由实例时,你可以提供 scrollBehavior 函数

js
const router = createRouter({
  history: createWebHashHistory(),
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return desired position
  }
})

scrollBehavior 函数接收 tofrom 路由对象,就像 导航守卫 一样。第三个参数 savedPosition 仅在这是 popstate 导航(由浏览器的后退/前进按钮触发)时可用。

该函数可以返回一个 ScrollToOptions 位置对象

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    // always scroll to top
    return { top: 0 }
  },
})

你也可以通过 el 传递 CSS 选择器或 DOM 元素。在这种情况下,topleft 将被视为相对于该元素的偏移量。

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    // always scroll 10px above the element #main
    return {
      // could also be
      // el: document.getElementById('main'),
      el: '#main',
      // 10px above the element
      top: 10,
    }
  },
})

如果返回一个假值或空对象,则不会发生滚动。

返回 savedPosition 将在使用后退/前进按钮导航时产生类似本机的行为

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
})

如果你想模拟“滚动到锚点”的行为

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return {
        el: to.hash,
      }
    }
  },
})

如果你的浏览器支持 滚动行为,你可以使其平滑

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      return {
        el: to.hash,
        behavior: 'smooth',
      }
    }
  }
})

延迟滚动

有时我们需要在页面滚动之前等待一段时间。例如,在处理过渡时,我们希望在滚动之前等待过渡完成。为此,你可以返回一个返回所需位置描述符的 Promise。以下是一个在滚动之前等待 500 毫秒的示例

js
const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ left: 0, top: 0 })
      }, 500)
    })
  },
})

可以将它与页面级过渡组件的事件挂钩,以使滚动行为与页面过渡配合良好,但由于用例中可能存在差异和复杂性,我们只提供这个原语来启用特定的用户端实现。