vant中list的使用以及首次加载触发两次解决问题

Rayna ·
更新时间:2024-11-10
· 1551 次阅读

目录

vant中list使用及首次加载触发两次

首次加载触发两次解决问题

vant中list列表组件使用

1. 基础结构

3.methods定义方法 

4.调用api渲染页面

vant中list使用及首次加载触发两次

以下是list的基本使用方法,主要原理就是当页面数据小于offset这个高度的时候,就会触发load,在load里面需要调用接口发送下一页的数据.所以发送完毕后需要将设置分页的属性加一,并将获取到的新值push进接收数据的数组里,而不是直接赋值,如果直接赋值那么数组里就只有新值,之前的值就被覆盖.

调用完以后将loading的样式关闭,并且判断数据库中还有没有数据,如果没有,就将finished为true,表示已经加载完毕了.

首次加载触发两次解决问题

1.在mounted或者create调用,原因是有可能在数据没回来的时候load就监测到数据低于高度,也发送了一次,等到数据回来时已经请求两次了.所以干脆不需要调用,交给load检测即可.

2.offset过于高,默认的高度是300,有一次获取数据一次只获取5条,虽然覆盖了页面高度,但稍作触碰就会二次发送.

3.请求的数据过少,请求的数据不足以覆盖页面就会二次加载,可以看文档list第一条示例便是.

<template> <div> <div class="groupBuyingList"> <!-- 加入加载 --> <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad" :offset='50' > <!-- 每个模块 --> <div class="activity" v-for="(item, index) in results" :key="index"> <img :src="item.photo" alt="" /> <div class="title">{{ item.cname }}</div> <div class="groupPeople"> <span>{{ item.groupLabel }}</span> </div> <div class="operation"> <div class="money"> <!-- 拼团价 --> <div class="groupMoney"> <span>¥</span>{{ item.groupPrice }} <span>起</span> </div> <!-- 原价 --> <div class="originalCost">¥{{ item.underlinedPrice }}</div> </div> <div class="share" @click="handleGo(item)"> <span> 去开团 </span> </div> </div> </div> </van-list> </div> </div> </template> <script> import { activityList } from "../../../api/appletGroupBuying/groupBuyingActivity"; export default { data() { return { userInfo: { // 条数 pageNum: 1, }, loading: false, //加载中状态 finished: false, //是否加载 // 接收列表数据 results: [], // 总条数 rowCount: "", }; }, mounted() { }, methods: { async activityList() { let res = await activityList(this.userInfo);//发送请求 // console.log(this.results); // 如果没有数据 if (res.data.ret.results === null) { this.results = []; this.finished = true; // 停止加载 } else { // 总条数 this.rowCount = res.data.ret.rowCount; // 将数据放入数组 this.results.push(...res.data.ret.results); this.loading = false; // 加载状态结束 // 如果list长度大于等于总数据条数,数据全部加载完成 //this.finished = true 结束加载状态 this.results.length >= this.rowCount ? (this.finished = true) : ""; } }, onLoad() { this.activityList(this.userInfo); // 调用上面方法,请求数据 this.userInfo.pageNum++; // 分页数加一 }, }, }; </script> <style lang="less" scoped> .groupBuyingList { padding: 20px; background: #f4f4f4; //每个活动 .activity { padding: 30px 35px; margin-bottom: 32px; width: 710px; background: #ffffff; border-radius: 20px; box-sizing: border-box; > img { width: 100%; } // 标题 .title { margin-top: 30px; width: 100%; height: 40px; font-size: 28px; font-weight: bold; line-height: 40px; color: #545353; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } // 拼团人数 .groupPeople { margin-top: 26px; margin-bottom: 14px; display: flex; align-items: center; span { padding: 0 3px 0 3px; border: 2px solid #ff7f00; border-radius: 10px; font-size: 24px; font-weight: 400; line-height: 33px; color: #ff7f00; } } .operation { display: flex; justify-content: space-between; .money { display: flex; // 拼团价 .groupMoney { display: flex; margin-right: 13px; height: 62px; font-size: 44px; font-weight: bold; line-height: 62px; color: #ff8105; span { font-size: 30px; } } // 原价 .originalCost { text-decoration: line-through; width: 119px; height: 40px; font-size: 28px; line-height: 60px; color: #b5b4b1; } } //分享获客 .share { width: 180px; height: 60px; background: #ff8105; display: flex; align-items: center; border-radius: 20px; span { width: 100%; line-height: 60px; text-align: center; font-size: 29px; font-weight: bold; line-height: 37px; color: #ffffff; } } } } } </style> vant中list列表组件使用

List 的运行机制:

List 会监听浏览器的滚动事件并计算列表的位置,当列表底部与可视区域的距离小于offset时,List 会触发一次 load 事件。

1. 基础结构 <van-list      v-model="loading"                     // 是否显示正在加载状态     :finished="finished"                 // 是否已经加载完成     finished-text="没有更多了"            // 加载完成提示文案     @load="onLoad"                         // 滚动条与底部距离offset时触发事件     offset="300"                        // 滚动条与底部距离offset时触发@load(默认300)     :error.sync="error"                 // 是否显示加载失败状态     error-text="请求失败,点击重新加载"    // 加载失败提示文案     >    <van-cell v-for='(item, index) in list' :key="index">  // 循环列表数据            <div>{{item}}循环出来的数据<div>    </van-cell>  </van-list>   2.data声明: data() {     return {       loading: false,         // 是否处在加载状态       finished: false,        // 是否已加载完成       error: false,           // 是否加载失败       list: [],               // 数据项       page: 1,                // 分页       page_size: 10           // 每页条数       total: 0                // 数据总条数     } } 3.methods定义方法  methods: {     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);     },   }, }; 4.调用api渲染页面

导入这个接口  import {  } from '@/api/xxx.js'

async onLoad () {   const res = await 接口方法名(this.channel.id, Date.now())   // 获取的数据   const arr = res.data.data.results // 它是一个数组   // 1. 追加数据到list   //    对数组进行展开   this.list.push(...arr)   // 2. 把loading设置为false   this.loading = false   // 3. 判断是否所有的数据全部加载完成,如果是:finished设为true   if (arr.length === 0) {     // 说明取不到数据了     this.finished = true   }   // 4. 页面上提示一下用户   this.$toast.success('成功加载数据') }

loading 和 finished 分别是什么含义?

List有以下三种状态,理解这些状态有助于你正确地使用List组件:

非加载中,loading为false,此时会根据列表滚动位置判断是否触发load事件(列表内容不足一屏幕时,会直接触发)

加载中,loading为true,表示正在发送异步请求,此时不会触发load事件

加载完成,finished为true,此时不会触发load事件

在每次请求完毕后,需要手动将loading设置为false,表示加载结束

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



解决问题 vant list

需要 登录 后方可回复, 如果你还没有账号请 注册新账号