Vue 页面滚动到指定位置(scrollIntoView)
Vue 页面滚动到指定位置(scrollIntoView)
在 Vue 项目开发中,经常会遇到这样的需求:
- 点击按钮跳转到页面某个区域
- 自动滚动到“猜你喜欢”
- 滚动到评论区
- 表单校验失败后定位到错误位置
- 锚点导航
Vue 中最简单优雅的方案:
1 | scrollIntoView() |
基础用法
例如:
1 | <h2 ref="recommendTitleRef"> |
1 | const recommendTitleRef = ref(null) |
然后:
1 | recommendTitleRef.value.scrollIntoView() |
页面就会自动滚动到该元素位置。
完整示例(Vue3)
template
1 | <h2 ref="recommendTitleRef"> |
script setup
1 | import { ref } from 'vue' |
scrollIntoView 参数详解
1. behavior
控制滚动动画。
smooth(推荐)
1 | behavior: 'smooth' |
效果:
1 | 平滑滚动动画 |
用户体验更好。
auto
1 | behavior: 'auto' |
效果:
1 | 瞬间跳转 |
没有动画。
2. block
控制元素最终停留的位置。
start(最常用)
1 | block: 'start' |
效果:
1 | 元素顶部对齐视口顶部 |
center
1 | block: 'center' |
效果:
1 | 元素滚动到屏幕中央 |
适合:
- 评论区定位
- 表单错误提示
- 图片预览
end
1 | block: 'end' |
效果:
1 | 元素底部对齐屏幕底部 |
nearest
1 | block: 'nearest' |
效果:
1 | 滚动最短距离 |
浏览器自动计算。
推荐写法
实际项目中推荐:
1 | recommendTitleRef.value.scrollIntoView({ |
原因:
- 兼容性好
- 用户体验自然
- 动画平滑
为什么需要 setTimeout?
很多人会发现:
1 | scrollIntoView() |
有时候不生效。
原因:
1 | DOM 还没真正渲染完成 |
所以:
1 | setTimeout(() => { |
等待页面完成渲染后再滚动。
更推荐的写法(nextTick)
实际上:
1 | Vue 官方更推荐 nextTick |
例如:
1 | import { nextTick } from 'vue' |
优点:
- 更稳定
- 更符合 Vue 响应式机制
- 不需要猜测时间
在 v-if 中使用注意事项
如果元素使用了:
1 | v-if |
必须确保:
1 | 元素已经渲染出来 |
否则:
1 | recommendTitleRef.value |
会是:
1 | null |
例如:
1 | await nextTick() |
后再执行滚动。
Vue2 写法
Vue2 中:
1 | <h2 ref="recommendTitleRef"> |
1 | this.$refs.recommendTitleRef.scrollIntoView({ |
实际应用场景
1. 跳转评论区
1 | commentRef.value.scrollIntoView({ |
2. 表单错误定位
1 | errorRef.value.scrollIntoView({ |
3. 锚点导航
1 | menuRef.value.scrollIntoView() |
4. 视频网站“猜你喜欢”
1 | recommendTitleRef.value.scrollIntoView({ |
非常适合:
- 视频网站
- 电商网站
- 博客系统
移动端注意事项
移动端浏览器有时候:
1 | 顶部会被 fixed 导航栏遮挡 |
解决方案:
1 | scroll-margin-top: 80px; |
例如:
1 | .target-title { |
这样滚动后不会被顶部导航覆盖。
推荐最终方案(生产环境)
1 | import { nextTick, ref } from 'vue' |
总结
Vue 页面滚动推荐使用:
1 | scrollIntoView() |
优点:
- API 简单
- 浏览器原生支持
- 平滑滚动
- 性能优秀
- 不需要额外库
推荐搭配:
1 | nextTick() |
一起使用。
这样:
1 | 稳定性会高很多 |