Vue 页面滚动到指定位置(scrollIntoView)
wxk1991 Lv3

Vue 页面滚动到指定位置(scrollIntoView)

在 Vue 项目开发中,经常会遇到这样的需求:

  • 点击按钮跳转到页面某个区域
  • 自动滚动到“猜你喜欢”
  • 滚动到评论区
  • 表单校验失败后定位到错误位置
  • 锚点导航

Vue 中最简单优雅的方案:

1
scrollIntoView()

基础用法

例如:

1
2
3
<h2 ref="recommendTitleRef">
猜你喜欢
</h2>
1
const recommendTitleRef = ref(null)

然后:

1
recommendTitleRef.value.scrollIntoView()

页面就会自动滚动到该元素位置。


完整示例(Vue3)

template

1
2
3
<h2 ref="recommendTitleRef">
猜你喜欢
</h2>

script setup

1
2
3
4
5
6
7
8
9
10
11
12
13
import { ref } from 'vue'

const recommendTitleRef = ref(null)

// 滚动到“猜你喜欢”位置
setTimeout(() => {
if (recommendTitleRef.value) {
recommendTitleRef.value.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
}, 150)

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
2
3
4
recommendTitleRef.value.scrollIntoView({
behavior: 'smooth',
block: 'start'
})

原因:

  • 兼容性好
  • 用户体验自然
  • 动画平滑

为什么需要 setTimeout?

很多人会发现:

1
scrollIntoView()

有时候不生效。

原因:

1
DOM 还没真正渲染完成

所以:

1
2
3
setTimeout(() => {

}, 150)

等待页面完成渲染后再滚动。


更推荐的写法(nextTick)

实际上:

1
Vue 官方更推荐 nextTick

例如:

1
2
3
4
5
6
7
8
import { nextTick } from 'vue'

nextTick(() => {
recommendTitleRef.value?.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
})

优点:

  • 更稳定
  • 更符合 Vue 响应式机制
  • 不需要猜测时间

在 v-if 中使用注意事项

如果元素使用了:

1
v-if

必须确保:

1
元素已经渲染出来

否则:

1
recommendTitleRef.value

会是:

1
null

例如:

1
await nextTick()

后再执行滚动。


Vue2 写法

Vue2 中:

1
2
3
<h2 ref="recommendTitleRef">
猜你喜欢
</h2>
1
2
3
this.$refs.recommendTitleRef.scrollIntoView({
behavior: 'smooth'
})

实际应用场景

1. 跳转评论区

1
2
3
commentRef.value.scrollIntoView({
behavior: 'smooth'
})

2. 表单错误定位

1
2
3
4
errorRef.value.scrollIntoView({
behavior: 'smooth',
block: 'center'
})

3. 锚点导航

1
menuRef.value.scrollIntoView()

4. 视频网站“猜你喜欢”

1
2
3
4
recommendTitleRef.value.scrollIntoView({
behavior: 'smooth',
block: 'start'
})

非常适合:

  • 视频网站
  • 电商网站
  • 博客系统

移动端注意事项

移动端浏览器有时候:

1
顶部会被 fixed 导航栏遮挡

解决方案:

1
scroll-margin-top: 80px;

例如:

1
2
3
.target-title {
scroll-margin-top: 80px;
}

这样滚动后不会被顶部导航覆盖。


推荐最终方案(生产环境)

1
2
3
4
5
6
7
8
9
10
11
12
import { nextTick, ref } from 'vue'

const recommendTitleRef = ref(null)

const scrollToRecommend = async () => {
await nextTick()

recommendTitleRef.value?.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}

总结

Vue 页面滚动推荐使用:

1
scrollIntoView()

优点:

  • API 简单
  • 浏览器原生支持
  • 平滑滚动
  • 性能优秀
  • 不需要额外库

推荐搭配:

1
nextTick()

一起使用。

这样:

1
稳定性会高很多