我写了一个更丝滑的上滑加载更多消息列表代码:
点击查看完整源码
<template> <view class="container"> <scroll-view class="scroll-view" scroll-y @scrolltoupper="onScrollToUpper" :scroll-top="scrollTop" :scroll-with-animation="false" :refresher-enabled="false" upper-threshold="150" style="height: 100vh;" > <view class="loading" v-if="isLoading">加载中...</view> <view v-for="(message, index) in messages" :key="message.id" class="message-item" > {{ message.content }} </view> </scroll-view> </view> </template> <script> export default { data() { return { messages: [], scrollTop: 0, isLoading: false, messageId: 0 // 用于生成唯一ID } }, mounted() { this.loadInitialMessages() }, methods: { async loadInitialMessages() { const initialMessages = await this.fetchMessages(20) this.messages = initialMessages this.$nextTick(() => { this.scrollToBottom() }) }, scrollToBottom() { // 延迟执行以确保DOM已更新 setTimeout(() => { const query = uni.createSelectorQuery().in(this) query.select('.scroll-view').boundingClientRect(data => { this.scrollTop = data.height * 2 }).exec() }, 100) }, async onScrollToUpper() { if (this.isLoading) return // 获取当前滚动位置和内容高度 const query = uni.createSelectorQuery().in(this) query.select('.scroll-view').boundingClientRect(async rect => { const oldHeight = rect.height const oldScrollTop = this.scrollTop this.isLoading = true console.log("加载更多") const newMessages = await this.fetchMessages(10) // 将新消息添加到顶部 this.messages = [...newMessages, ...this.messages] // 等待DOM更新 this.$nextTick(() => { query.select('.scroll-view').boundingClientRect(newRect => { const newHeight = newRect.height const heightDiff = newHeight - oldHeight // 调整滚动位置,保持视觉位置不变 this.scrollTop = oldScrollTop + heightDiff this.isLoading = false }).exec() }) }).exec() }, async fetchMessages(count) { // 模拟API请求 return new Promise(resolve => { setTimeout(() => { const messages = Array.from({ length: count }, () => ({ id: this.messageId++, content: `历史消息 ${this.messageId}` })) resolve(messages) }, 1000) }) } } } </script> <style> .container { height: 100vh; } .scroll-view { padding: 20px; box-sizing: border-box; } .message-item { padding: 10px; margin: 10px 0; background: #f5f5f5; border-radius: 5px; min-height: 40px; } .loading { text-align: center; padding: 10px; color: #999; } </style>
网友回复
浏览器中如何将WebM视频转成mp4视频?
parlant如何改成qwen 的apikey与baseurl?
如何写一个chrome插件实现截屏自动生成步骤图文教程转成pdf或网页?
python如何通过阿里云的api对域名进行解析和ecs主机服务器进行启动停止等操作?
Tesla Robotaxi可以让特斯拉车自动无人驾驶跑滴滴为车主赚钱,国内以后也会这样吗?
有没有可以监控安卓手机上的app打开后偷偷摸摸做了啥的监控软件?
webrtc进行p2p连接发送的文本音视频文件是否是加密的?
如何让一个可爱的三维动物通过three在浏览器中有表情动作的自然说话?
go与wails如何开发一个高性能的原生桌面应用?
python如何调用openai的api实现知识讲解类动画讲解视频的合成?