fix: 聊天页面默认在最底部

This commit is contained in:
2025-12-23 10:41:16 +08:00
parent 4580404dfd
commit 23a7af0426

View File

@@ -597,6 +597,7 @@ export default {
scrollViewHeight: 0, // 滚动视图高度
oldScrollViewHeight: 0, // 加载历史消息前的滚动高度
scrollViewStyle: '', // 动态设置 scroll-view 高度样式
currentScrollPosition: 0, // 仅用于内部记录位置,不绑定到 view
// 分页相关
page: 1,
@@ -712,25 +713,25 @@ export default {
this.$nextTick(() => {
const systemInfo = uni.getSystemInfoSync();
const windowHeight = systemInfo.windowHeight; // 窗口高度px
// 使用 uni.createSelectorQuery 获取头部和底部的高度
const query = uni.createSelectorQuery().in(this);
// 查询头部高度
query.select('.chat-header').boundingClientRect((headerRect) => {
const headerHeight = headerRect ? headerRect.height : 0;
// 查询底部高度
const query2 = uni.createSelectorQuery().in(this);
query2.select('.chat-footer').boundingClientRect((footerRect) => {
const footerHeight = footerRect ? footerRect.height : 0;
// 计算 scroll-view 的可用高度
const scrollHeight = windowHeight - headerHeight - footerHeight;
// 设置样式(使用 px 单位,因为系统信息返回的是 px
this.scrollViewStyle = `height: ${scrollHeight}px;`;
console.log('Scroll-view height calculated:', {
windowHeight,
headerHeight,
@@ -747,7 +748,13 @@ export default {
* 记录当前滚动位置
*/
onScroll(e) {
this.scrollTop = e.detail.scrollTop;
// >>>>>>>>>> 修复的核心改动 >>>>>>>>>>
// 移除: this.scrollTop = e.detail.scrollTop;
// 原因: 实时将滚动位置赋值回绑定了 :scroll-top 的变量,会导致 scroll-view
// 在用户触摸时不断尝试"矫正"位置,从而引发画面抽搐。
// 只需记录位置供内部逻辑使用即可,不要去更新绑定的属性。
this.currentScrollPosition = e.detail.scrollTop;
},
/**
@@ -858,13 +865,6 @@ export default {
}
},
/**
* 监听新消息事件
*/
/**
* 监听新消息事件
* 优化:只在用户不在滚动时才自动滚动到底部
*/
/**
* 监听新消息事件
*/
@@ -928,18 +928,18 @@ export default {
const mSenderId = m.sender_user_id || '';
const messageSenderId = message.sender_user_id || '';
if (mSenderId !== messageSenderId) return false;
// 比较消息内容(标准化后比较)
const mContent = normalizeContent(m.message_content || m.content || '');
const messageContent = normalizeContent(message.message_content || message.content || '');
if (mContent !== messageContent) return false;
// 时间戳匹配放宽到30秒处理网络延迟
const mTime = m.created_at || m.timestamp || 0;
const messageTime = message.created_at || message.timestamp || 0;
return Math.abs(mTime - messageTime) < 30000; // 30秒
});
if (tempMessageIndex !== -1) {
// 找到临时消息,用服务器返回的消息替换
this.messages[tempMessageIndex] = message;
@@ -953,16 +953,16 @@ export default {
const messageContent = normalizeContent(message.message_content || message.content || '');
const senderId = message.sender_user_id || '';
const messageTime = message.created_at || message.timestamp || 0;
const existingIndexByContent = this.messages.findIndex(m => {
const mContent = normalizeContent(m.message_content || m.content || '');
const mSenderId = m.sender_user_id || '';
const mTime = m.created_at || m.timestamp || 0;
// 内容相同标准化后、发送者相同、时间差在30秒内
return mContent === messageContent &&
mSenderId === senderId &&
Math.abs(mTime - messageTime) < 30000; // 放宽到30秒
return mContent === messageContent &&
mSenderId === senderId &&
Math.abs(mTime - messageTime) < 30000; // 放宽到30秒
});
if (existingIndexByContent !== -1) {
@@ -1280,7 +1280,7 @@ export default {
// 先清空 scroll-into-view避免与 scroll-top 冲突
// 注意:不清空 scrollTop避免重置滚动位置
this.scrollIntoView = '';
this.$nextTick(() => {
// 等待 DOM 更新
setTimeout(() => {
@@ -1297,7 +1297,7 @@ export default {
scrollToOldLastMessage() {
// 先清空 scroll-into-view避免优先级冲突
this.scrollIntoView = '';
this.$nextTick(() => {
// 使用 uni.createSelectorQuery 获取准确的滚动高度
const query = uni.createSelectorQuery().in(this);