VueRouter 基础教程系列 🎉
滚动行为
创建路由器时,可以使用 scrollBehavior 方法来控制路由切换时页面的滚动位置。
例如,滚动到顶部、保持原先的滚动位置、相对元素位置、锚点滚动等。
scrollBehavior 方法接受三个参数,分别是 to、from、savedPosition,其中 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 属性,此时 top 和 left 将被视为该元素的相对偏移量(页面会滚动到该元素所在的位置)。
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
scrollBehavior(to, from, savedPosition) {
return {
//el:document.querySelector('#box'),
el:'#box',
}
}
});
🤔 为什么滚动位置会相对于
left和top?很简单,因为现实中的滚动要么是水平滚动,要么就是垂直滚动。
滚动到锚点
利用相对元素位置滚动,我们还可以实现滚动到锚点的行为:
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'})