Skip to content

Pull down loading in Vue 3 using Composition API

Use the Composition API in Vue 3 to implement the pull-down loading function more conveniently. In the setup function, functions such as ref, reactive, and watchEffect can be used to implement functions similar to data, computed, and watch in Vue 2. Here is a simple sample code:

<template>
  <div class="list-container" ref="listContainer">
    <div v-for="(item, index) in list" :key="index">{{ item }}</div>
    <div v-if="isLoading" class="loading">正在加载...</div>
    <div v-else-if="hasMore" class="load-more" @click="loadMore">加载更多</div>
    <div v-else class="no-more">没有更多了</div>
  </div>
</template>

<script>
import { ref, onMounted, watch } from 'vue';

export default {
  setup() {
    // 定义数据和方法
    const list = ref([]);
    const page = ref(1);
    const isLoading = ref(false);
    const hasMore = ref(true);
    const loadMore = () => {
      isLoading.value = true;
      // 模拟异步请求
      setTimeout(() => {
        const newList = Array.from({ length: 10 }, (_, i) => `Item ${list.value.length + i + 1}`);
        list.value = [...list.value, ...newList];
        page.value++;
        isLoading.value = false;
        if (page.value > 5) {
          hasMore.value = false;
        }
      }, 1000);
    };

    // 监听滚动事件,判断是否触发加载更多
    const listContainer = ref(null);
    const handleScroll = () => {
      const { scrollTop, offsetHeight, scrollHeight } = listContainer.value;
      if (scrollTop + offsetHeight >= scrollHeight && !isLoading.value && hasMore.value) {
        loadMore();
      }
    };
    onMounted(() => {
      listContainer.value.addEventListener('scroll', handleScroll);
    });
    watch(hasMore, (newValue) => {
      if (!newValue) {
        listContainer.value.removeEventListener('scroll', handleScroll);
      }
    });

    // 返回数据和方法
    return {
      list,
      isLoading,
      hasMore,
      loadMore,
      listContainer,
    };
  },
};
</script>

<style scoped>
.list-container {
  height: 200px;
  overflow: auto;
}
.loading,
.load-more,
.no-more {
  height: 30px;
  line-height: 30px;
  text-align: center;
}
</style>

Source

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.