fix(消息列表): 优化消息列表更新逻辑和滚动加载
修复轮询更新时整个列表被替换的问题,改为只更新现有项状态 调整滚动加载逻辑,确保新数据正确追加到列表底部 修改滚动位置重置方式,使用固定值触发重新渲染
Showing
1 changed file
with
53 additions
and
6 deletions
| ... | @@ -38,7 +38,7 @@ | ... | @@ -38,7 +38,7 @@ |
| 38 | 38 | ||
| 39 | <!-- 消息列表内容 --> | 39 | <!-- 消息列表内容 --> |
| 40 | <scroll-view ref="scrollViewRef" class="conversation-list" :style="scrollStyle" :scroll-y="true" | 40 | <scroll-view ref="scrollViewRef" class="conversation-list" :style="scrollStyle" :scroll-y="true" |
| 41 | - @scrolltolower="loadMore" @scroll="scroll" :lower-threshold="20" :enable-flex="false" | 41 | + @scrolltolower="loadMore" :lower-threshold="100" :enable-flex="false" |
| 42 | :scroll-top="scrollTop"> | 42 | :scroll-top="scrollTop"> |
| 43 | <view v-for="conversation in filteredConversations" :key="conversation.id" | 43 | <view v-for="conversation in filteredConversations" :key="conversation.id" |
| 44 | class="conversation-item border-b border-gray-100 pb-2" | 44 | class="conversation-item border-b border-gray-100 pb-2" |
| ... | @@ -154,6 +154,7 @@ const mockMessages = ref([]) | ... | @@ -154,6 +154,7 @@ const mockMessages = ref([]) |
| 154 | 154 | ||
| 155 | /** | 155 | /** |
| 156 | * 轮询获取消息列表 | 156 | * 轮询获取消息列表 |
| 157 | + * 只更新现有数据的状态,不替换整个列表以保持滚动加载的数据 | ||
| 157 | */ | 158 | */ |
| 158 | const pollMessages = async () => { | 159 | const pollMessages = async () => { |
| 159 | try { | 160 | try { |
| ... | @@ -192,8 +193,41 @@ const pollMessages = async () => { | ... | @@ -192,8 +193,41 @@ const pollMessages = async () => { |
| 192 | create_time: item.create_time | 193 | create_time: item.create_time |
| 193 | })) | 194 | })) |
| 194 | 195 | ||
| 195 | - // 更新消息列表,保持当前页面状态 | 196 | + // 如果当前列表为空或者只有第一页数据,直接替换 |
| 197 | + if (conversations.value.length === 0 || page.value <= 1) { | ||
| 196 | conversations.value = transformedData | 198 | conversations.value = transformedData |
| 199 | + console.log('轮询:初始化或重置列表数据,数据量:', transformedData.length) | ||
| 200 | + } else { | ||
| 201 | + // 如果已经加载了多页数据,只更新现有项目的状态,不替换整个列表 | ||
| 202 | + console.log('轮询:更新现有数据状态,保持', conversations.value.length, '条数据') | ||
| 203 | + | ||
| 204 | + // 创建新数据的映射表,便于快速查找 | ||
| 205 | + const newDataMap = new Map(transformedData.map(item => [item.id, item])) | ||
| 206 | + | ||
| 207 | + // 更新现有数据的状态(如未读状态、最后消息等) | ||
| 208 | + conversations.value = conversations.value.map(existingItem => { | ||
| 209 | + const newItem = newDataMap.get(existingItem.id) | ||
| 210 | + if (newItem) { | ||
| 211 | + // 更新状态但保持在列表中的位置 | ||
| 212 | + return { | ||
| 213 | + ...existingItem, | ||
| 214 | + lastMessage: newItem.lastMessage, | ||
| 215 | + time: newItem.time, | ||
| 216 | + unread: newItem.unread | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + return existingItem | ||
| 220 | + }) | ||
| 221 | + | ||
| 222 | + // 检查是否有新的消息需要添加到列表顶部 | ||
| 223 | + const existingIds = new Set(conversations.value.map(item => item.id)) | ||
| 224 | + const newMessages = transformedData.filter(item => !existingIds.has(item.id)) | ||
| 225 | + | ||
| 226 | + if (newMessages.length > 0) { | ||
| 227 | + console.log('轮询:发现新消息', newMessages.length, '条,添加到列表顶部') | ||
| 228 | + conversations.value = [...newMessages, ...conversations.value] | ||
| 229 | + } | ||
| 230 | + } | ||
| 197 | } | 231 | } |
| 198 | } catch (error) { | 232 | } catch (error) { |
| 199 | console.error('轮询获取消息列表失败:', error) | 233 | console.error('轮询获取消息列表失败:', error) |
| ... | @@ -311,8 +345,8 @@ const setActiveTab = async (tabKey) => { | ... | @@ -311,8 +345,8 @@ const setActiveTab = async (tabKey) => { |
| 311 | hasMore.value = true; | 345 | hasMore.value = true; |
| 312 | // 重置加载状态 | 346 | // 重置加载状态 |
| 313 | loading.value = false; | 347 | loading.value = false; |
| 314 | - // 重置滚动位置 | 348 | + // 重置滚动位置 - 使用更可靠的方式 |
| 315 | - scrollTop.value = Math.random(); // 使用随机数触发scroll-view重新渲染 | 349 | + scrollTop.value = 0.1; // 使用固定的非零值触发scroll-view重新渲染 |
| 316 | setTimeout(() => { | 350 | setTimeout(() => { |
| 317 | scrollTop.value = 0; // 重置到顶部 | 351 | scrollTop.value = 0; // 重置到顶部 |
| 318 | }, 50); | 352 | }, 50); |
| ... | @@ -331,7 +365,10 @@ const setActiveTab = async (tabKey) => { | ... | @@ -331,7 +365,10 @@ const setActiveTab = async (tabKey) => { |
| 331 | }, 150); | 365 | }, 150); |
| 332 | } | 366 | } |
| 333 | 367 | ||
| 334 | -// 加载更多数据 | 368 | +/** |
| 369 | + * 加载更多数据 | ||
| 370 | + * 向下滚动时加载下一页数据并追加到现有列表 | ||
| 371 | + */ | ||
| 335 | const loadMore = async () => { | 372 | const loadMore = async () => { |
| 336 | if (loading.value || !hasMore.value) { | 373 | if (loading.value || !hasMore.value) { |
| 337 | return | 374 | return |
| ... | @@ -339,6 +376,7 @@ const loadMore = async () => { | ... | @@ -339,6 +376,7 @@ const loadMore = async () => { |
| 339 | 376 | ||
| 340 | try { | 377 | try { |
| 341 | loading.value = true | 378 | loading.value = true |
| 379 | + console.log('加载更多数据,当前页码:', page.value, '当前列表项数:', conversations.value.length) | ||
| 342 | 380 | ||
| 343 | // 构建请求参数,同时包含状态筛选和关键字搜索 | 381 | // 构建请求参数,同时包含状态筛选和关键字搜索 |
| 344 | const params = { | 382 | const params = { |
| ... | @@ -375,15 +413,24 @@ const loadMore = async () => { | ... | @@ -375,15 +413,24 @@ const loadMore = async () => { |
| 375 | })) | 413 | })) |
| 376 | 414 | ||
| 377 | if (transformedData.length > 0) { | 415 | if (transformedData.length > 0) { |
| 378 | - conversations.value.push(...transformedData) | 416 | + // 保存当前列表长度,用于调试 |
| 417 | + const prevLength = conversations.value.length | ||
| 418 | + | ||
| 419 | + // 追加新数据到现有列表 | ||
| 420 | + conversations.value = [...conversations.value, ...transformedData] | ||
| 421 | + | ||
| 422 | + // 增加页码 | ||
| 379 | page.value++ | 423 | page.value++ |
| 424 | + | ||
| 380 | // 判断是否还有更多数据 | 425 | // 判断是否还有更多数据 |
| 381 | hasMore.value = transformedData.length === pageSize | 426 | hasMore.value = transformedData.length === pageSize |
| 382 | } else { | 427 | } else { |
| 383 | hasMore.value = false | 428 | hasMore.value = false |
| 429 | + console.log('没有更多数据') | ||
| 384 | } | 430 | } |
| 385 | } else { | 431 | } else { |
| 386 | hasMore.value = false | 432 | hasMore.value = false |
| 433 | + console.log('API返回无数据') | ||
| 387 | } | 434 | } |
| 388 | } catch (error) { | 435 | } catch (error) { |
| 389 | console.error('加载更多消息失败:', error) | 436 | console.error('加载更多消息失败:', error) | ... | ... |
-
Please register or login to post a comment