使用vant长列表组件vant-list

1、需求背景

一个页面展示从列表请求到的数据,向上滑动时发送请求接口下一页数据,一直往上滑动可以一直请求数据,直到滑动到最后一页。

2、技术路径

vue3+vant4

3、不依赖vant组件实现

展示内容,一进入页面加载数据,如果数据还没请求到显示"数据加载中..."的提示,加载到数据后展示数据,如果数据为空展示"暂无内容,请稍后查看"的提示,加载到数据底部时在数据后面显示"暂无更多内容..."的提示。

index.vue 复制代码
<div class="main" ref="main">
    <div v-for="item in dataLists" :key="item.id">
       {{ item.content }}
    </div>
    <div v-if="loading" ref="loading">
       数据加载中...
    </div>
    <div v-if="!loading && dataLists.length === 0">
      暂无内容,请稍后查看
    </div>
    <div v-if="latestId == '-1' && dataLists.length !== 0">
      暂无更多内容...
    </div>
</div>

样式,允许超过页面的部分可以滚动

index.less 复制代码
  .main {
    width: 100%;
    height: 100vh;
    overflow-y: auto;
  }

数据处理逻辑 ,在页面创建的时候就从接口获取数据,监听滚动事件,页面翻页接口是根据前一页的最后一个id来请求下一页数据,当最后一页数据为空时,把最后一个id置为"-1"结束下一次请求。

监听页面滚动,页面容器 scrollTop+clientHeight >= scrollHeight时请求下一页。

index.js 复制代码
export default {
  data() {
    return {
      dataLists: [],
      loading: false,
    }
  },
  created() {
    this.getList();
  },
  mounted() {
    const scrollContainer = this.$refs.main;
    scrollContainer.addEventListener("scroll", this.handleScroll);
  },
  beforeDestroy() {
    const scrollContainer = this.$refs.main;
    scrollContainer.removeEventListener("scroll", this.handleScroll);
  },
  methods: {
    //从接口获取数据
    getList(params) {
      this.loading = true;
      return baseApi.getList({
        name: "接口名",
        data: params
      })
        .then((res) => {
          if (res.data.list.length) {
            this.latestId = res.data.list[res.data.list.length - 1].id;
            this.dataLists = res.data.list
          } else {
            this.loading = false;
            this.latestId = "-1";
          }
        })
        .catch((err) => {
          if (this.$refs.loading) {
            this.$refs.loading.innerText = "数据异常,暂时无法显示~";
          }
        });
    },
    // 页面滚动
    handleScroll() {
      const mainContainer = this.$refs.main;
      const scrollHeight = mainContainer.scrollHeight;
      const clientHeight = mainContainer.clientHeight;
      const scrollTop = mainContainer.scrollTop;
      if (scrollTop + clientHeight >= scrollHeight - 100) {//给100px高度,滑到底部提前加载数据
        if (this.latestId != "-1" && this.loading == false) {
          this.getList(参数);
        }
      }
      if (scrollTop < -100) {
        if (this.loading == false) {
          this.dataLists = [];
          this.latestId = "";
          this.getList(参数);
        }
      }
    },
  }
}

4、使用vant-list组件实现

安装并导入依赖 npm i vant

main.js 复制代码
import { createApp } from 'vue'; 
import 'vant/lib/index.css'
import { List } from 'vant'; 
const app = createApp(App)
app.use(List)
app.mount("#app")

页面元素 ,使用vant-list组件,通过loading和finished两个变量控制加载状态,当组件滚动到底部的时候,会触发load事件并将loading设置成true。此时可以发起异步请求并更新数据,更新完毕后将loading设置为false。若数据全部加载完毕,则将finished设置为true。

列表数据加载失败,将error设置为true即可显示错误提示,用户点击错误提示提示会重新触发load事件。

index.vue 复制代码
<div class="main"  ref="main">
    <van-list :loading="loading"  loading-text="数据加载中..." :finished="finished" finished-text="暂无更多内容..." :error="error" error-text="暂无内容,请稍后查看" @load="onLoad()">
      <div v-for="item in dataLists" :key="item.id" >
         {{ item.content }}
      </div>
    </van-list>
  </div>

样式

index.less 复制代码
  .main {
    width: 100%;
    height: 100vh;
    overflow-y: auto;
  }

逻辑处理

index.js 复制代码
export default {
  data() {
    return {
      dataLists: [],
      loading: false,
      finished: false,
      error: false,
    }
  },
  created() {
    this.getList();
  },
  methods: {
    onLoad() {
      this.loading = true
      this.getDataListInfo(参数);
    },
    //从接口获取数据
    getList(params) {
      this.loading = true;
      return baseApi.getList({
        name: "接口名",
        data: params,
      })
        .then((res) => {
          this.loading = false;
          if (res.data.list.length) {
            this.latestId = res.data.list[res.data.list.length - 1].id;
            this.dataLists = res.data.list
          } else {
            this.finished = true;
            this.latestId = "-1";
          }
        })
        .catch((err) => {
          this.loading = false;
          this.error = true;
        });
    },
  }
}
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端