返回

剥茧抽丝,小程序分页组件的从无到有

前端

可复用分页组件:在小程序中高效加载数据

在小程序开发中,我们经常会遇到这样的场景:在一个页面中,有多个tab切换列表,每个列表都需要分页功能。为了避免重复编写分页逻辑,并提高代码的可维护性,将分页封装为一个组件是一个明智的选择。

分页组件的关键点

在实现可复用分页组件之前,我们需要考虑以下几个关键点:

  • 数据加载:
    • 首次加载时,只加载默认tab页的首页数据,其他tab页的数据等到点击到对应tab页才开始加载。
    • 回到已加载过的tab页,保留原数据,不重新加载。
  • 触发分页:
    • 触发分页的事件是滚动到页面的底部。
    • 在小程序中,可以使用pageScrollToBottom事件来监听滚动事件。
  • 组件封装:
    • 将分页逻辑封装在一个组件中,并提供必要的属性和方法。
    • 组件的属性包括:当前tab页、默认tab页、分页数据、加载状态等。
    • 组件的方法包括:加载更多数据、重置数据等。

实现分页组件

以下是分页组件的详细实现过程:

1. 创建组件:

const app = getApp()

Component({
  properties: {
    currentTab: {
      type: String,
      value: '',
    },
    defaultTab: {
      type: String,
      value: '',
    },
    pageData: {
      type: Array,
      value: [],
    },
    loading: {
      type: Boolean,
      value: false,
    },
  },
  data: {
    // 当前加载的tab页
    currentTabPage: '',
  },
  methods: {
    // 加载更多数据
    loadMore() {
      if (this.data.loading) {
        return
      }

      this.setData({
        loading: true,
      })

      const page = this.data.pageData[this.data.currentTabPage].page + 1
      wx.request({
        url: `https://example.com/api/list?page=${page}`,
        success: (res) => {
          const data = res.data.data
          this.setData({
            loading: false,
            ['pageData.' + this.data.currentTabPage + '.list']: this.data.pageData[this.data.currentTabPage].list.concat(data),
            ['pageData.' + this.data.currentTabPage + '.page']: page,
          })
        },
      })
    },

    // 重置数据
    reset() {
      this.setData({
        currentTabPage: '',
        pageData: [],
      })
    },
  },

  lifetimes: {
    attached() {
      // 首次加载时,只加载默认tab页的首页数据
      this.setData({
        currentTabPage: this.data.defaultTab,
      })

      this.loadMore()
    },

    detached() {
      // 重置数据
      this.reset()
    },
  },

  pageLifetimes: {
    show() {
      // 回到已加载过的tab页,保留原数据,不重新加载
      if (this.data.pageData[this.data.currentTab]) {
        this.setData({
          currentTabPage: this.data.currentTab,
        })
      } else {
        this.loadMore()
      }
    },
  },
})

2. 使用组件:

<template>
  <view class="container">
    <view class="tab-bar">
      <view class="tab-item" wx:for="{{ tabs }}" wx:key="item.id" data-tab="{{ item.id }}" bindtap="handleTabChange">{{ item.name }}</view>
    </view>
    <view class="list-container">
      <pagination current-tab="{{ currentTab }}" default-tab="{{ defaultTab }}" page-data="{{ pageData }}" loading="{{ loading }}"></pagination>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      tabs: [
        { id: 'tab1', name: 'Tab1' },
        { id: 'tab2', name: 'Tab2' },
        { id: 'tab3', name: 'Tab3' },
      ],
      currentTab: 'tab1',
      defaultTab: 'tab1',
      pageData: {
        tab1: {
          list: [],
          page: 1,
        },
        tab2: {
          list: [],
          page: 1,
        },
        tab3: {
          list: [],
          page: 1,
        },
      },
      loading: false,
    }
  },

  methods: {
    handleTabChange(e) {
      const tabId = e.currentTarget.dataset.tab
      this.setData({
        currentTab: tabId,
      })

      if (!this.pageData[tabId].list.length) {
        this.setData({
          loading: true,
        })

        wx.request({
          url: `https://example.com/api/list?page=1`,
          success: (res) => {
            const data = res.data.data
            this.setData({
              loading: false,
              ['pageData.' + tabId + '.list']: data,
              ['pageData.' + tabId + '.page']: 1,
            })
          },
        })
      }
    },
  },
}
</script>

优点

使用分页组件的好处包括:

  • 代码复用: 避免重复编写分页逻辑,提高开发效率和代码可维护性。
  • 数据管理: 根据当前加载的tab页动态加载数据,优化页面性能和用户体验。
  • 加载更多数据: 通过监听滚动事件,在用户滚动到页面底部时自动加载更多数据,提供流畅的用户交互。

常见问题解答

  1. 如何重置分页组件?

    • 使用reset方法即可重置分页组件,它会清空当前加载的tab页数据和分页信息。
  2. 如何判断当前加载的tab页是否已加载过数据?

    • 检查pageData对象中当前加载的tab页对应的list数组是否有数据。如果有数据,则表示该tab页已加载过数据。
  3. 如何自定义分页加载的阈值?

    • 可以通过修改监听滚动事件的阈值来自定义分页加载的阈值。例如,在小程序中,可以通过设置pageScrollToBottom事件的threshold属性来调整阈值。
  4. 如何处理分页加载失败的情况?

    • loadMore方法中,可以添加处理分页加载失败的逻辑,例如显示错误提示或重新尝试加载。
  5. 如何优化分页加载的性能?

    • 避免在每次加载数据时都重新渲染整个列表。可以使用虚拟列表或惰性加载等技术来优化渲染性能。