014:vue3 van-list van-pull-refresh实现上拉加载,下拉刷新

发布于:2024-04-14 ⋅ 阅读:(181) ⋅ 点赞:(0)

1. 实现上拉加载,下拉刷新效果

  1. 通过下拉刷新加载下一页接口
    请添加图片描述

2. van-list,van-pull-refresh组件详解

  1. Vant 是一个轻量、可靠的移动端组件库,使用该框架的 van-list 组件和 van-pull-refresh 组件可实现上述功能
  2. 在移动端项目开发中有列表页面开发,需要实现上拉加载下一页数据下拉刷新页面

2.1 van-list组件

用于展示长列表,当列表即将滚动到底部时,会触发事件并加载更多列表项。用该组件可实现上拉加载
List 组件通过 loadingfinished 两个变量控制加载状态,当组件滚动到底部时,会触发 load 事件并将 loading 设置成 true。此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。若数据已全部加载完毕,则直接将 finished 设置成 true 即可

<van-list
  v-model="loading"
  :finished="finished"
  finished-text="没有更多了"
  @load="onLoad"
>
  <van-cell v-for="item in list" :key="item" :title="item" />
</van-list>

onLoad() {
   // 异步更新数据
   // setTimeout 仅做示例,真实场景中一般为 ajax 请求
   setTimeout(() => {
     for (let i = 0; i < 10; i++) {
       this.list.push(this.list.length + 1);
     }
     // 加载状态结束
     this.loading = false;
     // 数据全部加载完成
     if (this.list.length >= 40) {
       this.finished = true;
     }
   }, 1000);
 }

2.2 van-pull-refresh组件

下拉刷新时会触发 refresh 事件,在事件的回调函数中可以进行同步或异步操作,操作完成后将 v-model 设置为 false,表示加载完成。

<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
  <p>刷新次数: {{ count }}</p>
</van-pull-refresh>
onRefresh() {
   setTimeout(() => {
     Toast('刷新成功');
     this.isLoading = false;
     this.count++;
   }, 1000);
 }

3. 完整案例

<template>
  <div class="main">
    <van-pull-refresh
      v-model="refreshing"
      @refresh="onRefresh"
      loosing-text="释放即可刷新"
      pulling-text="下拉刷新"
    >
      <van-list
        v-model:loading="loading"
        :finished="finished"
        finished-text="没有更多了"
        loading-text="加载中..."
        @load="onLoad"
      >
        <div
          v-for="(_item, index) in listData"
          :key="index"
          class="wallet"
        >
          <div class="content">
            .....内容
          </div>
        </div>
      </van-list>
    </van-pull-refresh>
  </div>
</template>
<script setup lang="ts">
import { Async_cashList } from "@/server/user";
const listData = ref([]);
const loading = ref(false);
const finished = ref(false);
const refreshing = ref(false);
const pageParams = ref({
  page: 0,
  size: 20
});

const onLoad = () => {
  if (refreshing.value) {
    listData.value = [];
    refreshing.value = false;
  }
  getList();
};

const onRefresh = () => {
  pageParams.value.page = 0;
  listData.value = [];
  refreshing.value = false;
  finished.value = false;
  loading.value = true;
  getList();
};

const getList = async () => {
  try {
    let { list }: any = await Async_cashList({
      page: pageParams.value.page,
      size: pageParams.value.size,
    });
    loading.value = false;
    if (!list) {
      // 如果返回数据为空,表示已加载完成
      finished.value = true;
    } else {
      listData.value = listData.value.concat(list);
      pageParams.value.page++;
    }
  } catch (error) {
    console.error(error);
  } finally {
    loading.value = false;
  }
};

</script>
<style scoped lang="scss">
.main {
  width: 100%;
  padding: 12px;
  height: 100vh;
}

.wallet {
  display: flex;
  justify-content: flex-start;
  margin-bottom: 6px;

  .content {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #11202f;
    padding: 12px;
    border-radius: 6px;
  }
}
</style>

4. 坑点:加载页面会一直调用加载接口

  1. 开发中遇到一个坑点,就是不管怎么调页面都是默认一进去会加载完所有的请求,比如一页有20条,一共100条,就会执行5次接口,请求完数据,如下所示

请添加图片描述

  1. 这并不是我们想要的,我们要的是进去加载第一页,根据手动下拉去加载剩余的数据,下面的方式可解决

需要设置页面的固定高度,van-list需要验证页面是否触底,如果没用触底,就会继续加载页面,触底了就不会继续调用接口了

.main {
  width: 100%;
  padding: 12px;
  height: 100vh; // 就是这行加一个固定的高度即可
}

网站公告

今日签到

点亮在社区的每一天
去签到