滚动行为
当路由切换时,浏览器默认会保持当前的滚动位置。vitarx-router 提供了 scrollBehavior 配置项,让你可以精确控制页面切换时的滚动行为。
scrollBehavior 配置
在 createRouter 中配置 scrollBehavior 函数:
ts
import { createRouter } from 'vitarx-router'
const router = createRouter({
routes: [...],
scrollBehavior(to, from, savedPosition) {
// 返回滚动目标
return { top: 0, left: 0, behavior: 'smooth' }
}
})函数签名:
ts
type BeforeScrollCallback = (
to: RouteLocation,
from: RouteLocation,
savedPosition: ScrollPosition | null
) => ScrollTarget | false | void返回值说明
| 返回值 | 说明 |
|---|---|
ScrollTarget | 滚动到指定位置 |
false | 禁用路由器内部的滚动处理 |
void | 使用默认行为 |
ScrollTarget 接口
ts
interface ScrollTarget {
/** 滚动到指定元素(CSS 选择器) */
el?: string
/** 水平滚动位置 */
left?: number
/** 垂直滚动位置 */
top?: number
/** 滚动行为:'auto' | 'instant' | 'smooth' */
behavior?: ScrollBehavior
}常见用法
滚动到顶部:
ts
scrollBehavior() {
return { top: 0, left: 0 }
}平滑滚动到顶部:
ts
scrollBehavior() {
return { top: 0, left: 0, behavior: 'smooth' }
}滚动到指定元素:
ts
scrollBehavior(to) {
if (to.hash) {
return { el: to.hash, behavior: 'smooth' }
}
return { top: 0 }
}禁用滚动:
ts
scrollBehavior() {
return false
}默认行为
如果没有配置 scrollBehavior,路由器使用以下默认行为:
- 如果目标路由包含
hash(如#section),滚动到对应元素 - 否则滚动到页面顶部
{ top: 0, left: 0 }
savedPosition
savedPosition 参数在用户使用浏览器的前进/后退按钮时提供之前保存的滚动位置:
ts
scrollBehavior(to, from, savedPosition) {
// 如果有保存的位置(前进/后退),恢复到之前的位置
if (savedPosition) {
return savedPosition
}
// 如果有 hash,滚动到对应元素
if (to.hash) {
return { el: to.hash }
}
// 否则滚动到顶部
return { top: 0, left: 0 }
}INFO
savedPosition 仅在使用 router.go()、router.back()、router.forward() 导航时才有值,编程式导航(push/replace)时为 null。
完整示例
ts
import { createRouter } from 'vitarx-router'
import type { RouteLocation, ScrollPosition } from 'vitarx-router'
const router = createRouter({
routes: [...],
scrollBehavior(
to: RouteLocation,
from: RouteLocation,
savedPosition: ScrollPosition | null
) {
// 1. 前进/后退时恢复滚动位置
if (savedPosition) {
return { ...savedPosition, behavior: 'auto' }
}
// 2. 有 hash 时滚动到锚点
if (to.hash) {
return { el: to.hash, behavior: 'smooth' }
}
// 3. 从列表页进入详情页时保持位置
if (from.path === '/articles' && to.path.startsWith('/article/')) {
return false
}
// 4. 默认滚动到顶部
return { top: 0, left: 0, behavior: 'instant' }
}
})