+
110
-

uniapp如何实现scrollview无缝上滑丝滑滚动加载更多历史消息记录?

uniapp如何实现scrollview无缝上滑丝滑滚动加载更多历史消息记录?

上滑滚动过程中加载更多内容不出现卡顿。

网友回复

+
19
-

800_auto

我写了一个更丝滑的上滑加载更多消息列表代码:

点击查看完整源码

+
16
-

在uniapp中实现无缝上滑滚动加载更多历史消息记录的效果,可以通过 scroll-view 组件结合 onScrollToUpper 或 onScroll 事件来完成。为了保证滚动过程中的流畅性和用户体验,关键在于数据的预加载和滚动事件的处理。以下是具体的实现思路:

1. 使用 scroll-view 组件

scroll-view 组件可以监听滚动事件,并支持上下滚动加载更多内容。

<scroll-view
  scroll-y
  @scrolltoupper="loadMoreMessages"
  @scroll="handleScroll"
  :scroll-into-view="toView"
  style="height: 100vh;">

  <view v-for="(message, index) in messages" :key="index" :id="'msg' + index">
    {{ message }}
  </view>

</scroll-view>
2. 加载更多消息

通过 scrolltoupper 事件监听到用户上滑到顶部时,加载更多历史消息。

export default {
  data() {
    return {
      messages: [],      // 存储消息列表
      toView: ''...

点击查看剩余70%

+
11
-

可以使用虚拟列表只渲染可视区域,提供性能,我的代码如下:

<template>
  <view class="container">
    <scroll-view 
      ref="scrollView"
      class="scroll-view"
      scroll-y 
      @scroll="onScroll"
      :scroll-top="scrollTop"
      :scroll-with-animation="false"
      :refresher-enabled="false"
      style="height: 100vh;"
    >
      <view class="loading" v-if="isLoading">加载中...</view>
      <!-- 用于撑开高度的容器 -->
      <view :style="{ height: totalHeight + 'px' }">
        <!-- 只渲染可视区域的消息 -->
        <view 
          v-for="message in visibleMessages" 
          :key="message.id" 
          class="message-item"
          :style="{ 
            transform: `translateY(${message.top}px)`,
            position: 'absolute',
            width: 'calc(100% - 40px)'
          }"
        >
          {{ message.content }}
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
function throttle(fn, delay) {
  let timer = null;
  return function(...args) {
    if (timer) return;
    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  }
}

export default {
  data() {
    return {
      allMessages: [], // 所有消息数据
      visibleMessages: [], // 可视区域的消息
      scrollTop: 0,
      isLoading: false,
      messageId: 0,
      scrollQuery: null,
      itemHeight: 60, // 每条消息的固定高度
      bufferSize: 5, // 上下额外渲染的消息数量
      viewportHeight: 0, // 可视区域高度
      startIndex: 0, // 当前渲染的起始索引
      endIndex: 0, // 当前渲染的结束索引
    }
  },
  
  computed: {
    totalHeight() {
      return this.allMessages.length * this.itemHeight;
    },
  },
  
  mounted() {
    this.scrollQuery = uni.createSelectorQuery().in(this);
    this.initViewport();
    this.loadInitialMe...

点击查看剩余70%

我知道答案,我要回答