vue3 使用 vant 实现列表上拉加载、下拉刷新

发布时间 2023-05-26 15:25:15作者: ZerlinM

实现方式

实现了列表的上拉加载、下拉刷新,使用的是vant库中的 ListPullRefresh


onLoad 和 onRefresh方法中 isLoading.value = true; // 重点 为重点,是触发fetchListData方法的关键,但是这个在官方文档中并未表明,导致绕了很大弯才解决。

直接上代码

<template>
  <div class="listCon">
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list
        v-model:loading="isLoading"
        :finished="finished"
        finished-text="没有更多了"
        @load="onLoad"
      >
        <div v-if="listData?.records && listData.records.length">
          <div v-for="item in listData.records" :key="item.id">
            <div>{{ item.name || "--" }}</div>
          </div>
        </div>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { useStore } from "vuex";
import { getList } from "@/services/listService.js";

const defaultPageSize = 20;

const refreshing = ref(false);
const isLoading = ref(false);
const finished = ref(false);
const params = ref({ pageIndex: 0, pageSize: defaultPageSize, districtId: 1 });
const listData = ref({
  records: [],
  pageIndex: 1,
  pageSize: defaultPageSize,
  total: 0,
  totalPage: 0,
});

const fetchListData = async () => {
  if (
    // 如果总页数小于等于现页数,并且不是第一次加载, 或者正在加载数据 直接跳出不请求
    listData.value.totalPage <= params.value.pageIndex &&
    params.value.pageIndex !== 1
  ) {
    finished.value = true;
    return;
  }
  const res = await getList(params.value);
  if (res.code === 200) {
    if (refreshing.value) {
      refreshing.value = false;
    }
    isLoading.value = false;

    const skuDataReq = res.data;

    skuDataReq.records = (
      params.value.pageIndex === 1 ? [] : listData.value.records
    ).concat(skuDataReq.records);

    skuDataReq.totalPage = Math.ceil(skuDataReq.total / defaultPageSize);

    listData.value = {
      ...skuDataReq,
    };
  }
};

const onLoad = () => {
  console.log("触底");
  isLoading.value = true; // 重点
  params.value.pageIndex++;
  fetchListData();
};

const onRefresh = () => {
  // 重新加载数据
  console.log("刷新");

  finished.value = false;
  // 将 loading 设置为 true,表示处于加载状态
  isLoading.value = true; // 重点

  params.value.pageIndex = 1;
  fetchListData();
};
</script>

<style lang="scss" scoped>
.listCon {
  width: 100%;
  height: 100vh;
}

:deep(.pageRefresh) .van-pull-refresh__track {
  min-height: 100vh;
  background-color: #f5f5f5;
}
</style>

备注

代码中res的数据格式如下:

res = {
  code: 200,
  data: {
    total: 86,
    pageIndex: 1,
    pageSize: 10,
    records: [
      {name: 'xxx'},
      {name: 'xxx'},
    ]
  }
}

因为获取到的数据中没有totalPage,所以代码中是自己计算了totalPage,可无视。