# 大模型输出的文本展示到页面上并实现自动滚动
思路:只需要在拼接字符的时候调用scrollIntoView或scrollTo就可以了
使用scrollIntoView()让页面滚动,使目标元素进入可视区域
const scrollThrottle = ref(false)
const scrollToLatestMessage = () => {
const sessionEm = conversationRef.value
if (sessionEm) {
if (scrollThrottle.value) return
scrollThrottle.value = true
requestAnimationFrame(() => {
conversationRef.value?.scrollIntoView({ behavior: 'smooth', block: 'end' })
setTimeout(() => {
scrollThrottle.value = false
}, 100)
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这里添加了Throttle节流控制,避免短时间内多次触发滚动操作
使用 requestAnimationFrame:将滚动操作放在 requestAnimationFrame 回调中执行,可以确保在浏览器的下一帧渲染时进行滚动,提高性能和流畅度。
| 属性 | 说明 | 常用值 |
|---|---|---|
behavior | 滚动动画行为 | 'auto'(默认) or 'smooth' |
block | 垂直方向对齐方式 | 'start'(顶部)、'end'(底部)、'nearest' |
inline | 水平方向对齐方式 | 通常不需要设,除非横向滚动 |
element.scrollIntoView({
behavior: 'smooth',
block: 'end'
})
1
2
3
4
2
3
4
这个写法会平滑地滚动,让元素出现在容器的底部。
# 如何区分用户滚动和代码滚动
给需要滚动的容器的父元素添加一个wheel事件,使用鼠标滚轮滚动时就会触发这个wheel事件,然后通过响应式状态来判断
const conversationRef = useTemplateRef('conversationRef')
const scrollContainerRef = useTemplateRef('scrollContainerRef')
const userScrolled = ref(false)
const scrollThrottle = ref(false)
const scrollToLatestMessage = () => {
const sessionEm = conversationRef.value
if (sessionEm) {
if (scrollThrottle.value || userScrolled.value) return // 如果用户手动滚动,则不再自动滚动
scrollThrottle.value = true
requestAnimationFrame(() => {
conversationRef.value?.scrollIntoView({ behavior: 'smooth', block: 'end' })
setTimeout(() => {
scrollThrottle.value = false
}, 100)
})
}
}
onMounted(() => {
if (scrollContainerRef.value) {
scrollContainerRef.value.addEventListener(
'wheel',
debounce(() => {
console.log('用户滚动了')
userScrolled.value = true
}, 100)
)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30