自动滚动到底部
2026/3/13大约 2 分钟
问题背景
在项目中,需要在用户发送消息后,自动滚动到消息列表的底部,以展示最新的消息。
解决方案
我们可以使用 uni-app 提供的 scroll-view 组件,结合 JavaScript 代码,实现自动滚动到最底部的功能。
scroll-view 是可滚动视图区域,用于区域滚动。
注意
高度设置:scroll-view 必须设置固定高度(如 height: 100vh 或计算后的高度),否则无法滚动。
内容溢出 :内部内容高度必须超过 scroll-view 高度才会出现滚动条。
动态内容 :消息列表动态增加时,需要在数据更新后延迟执行滚动(使用 nextTick 或 setTimeout)。
虚拟列表 :消息数量过多时,考虑使用虚拟列表只渲染可视区域内容,提高性能。
滚动动画 :
scroll-with-animation为 true 时,大量消息可能导致动画卡顿,可酌情关闭。
<template>
<view class="chatbot">
<scroll-view class="scrollView" scroll-y="true" :scroll-top="scrollTop" scroll-with-animation>
<view class="messageWrapper">
<view v-for="(msg, index) in messages" :key="index" class="message" :class="msg.role">
<view class="avatar" v-if="msg.role === 'ai'">
<image :src="avatar[msg.role]" mode="aspectFill" />
</view>
<view class="content" :class="msg.role+'Content'">
<rich-text :nodes="msg.role === 'ai' ? markdownToHtml(msg.content) : msg.content"></rich-text>
</view>
<view class="avatar" v-if="msg.role === 'human'">
<image :src="avatar[msg.role]" mode="aspectFill" />
</view>
</view>
</view>
</scroll-view>
<view class="input-area">
<input v-model="inputMessage" type="text" placeholder="请输入..." class="input" ref="input" />
<button @click="sendMessage" class="send-btn" :class="isSending?'disabled':''" :disabled="isSending">发送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
scrollTop: 0, // 滚动条位置
scrollViewHeight: 300, // 滚动视图高度
}
},
methods: {
scrollToBottom() {
this.$nextTick(() => {
uni.createSelectorQuery().in(this).select('.messageWrapper').boundingClientRect((res) => {
this.scrollTop = res.height-this.scrollViewHeight > 0 ? res.height-this.scrollViewHeight : 0;
}).exec();
});
},
}
}
</script>