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

目录
  • 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,表示加载结束

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Vant-list 上拉加载及下拉刷新的问题

    目录 Vant-list 上拉加载及下拉刷新 vant下拉刷新与上拉加载一起使用问题 下拉刷新触发两次 list与pull 解决方法是 Vant-list 上拉加载及下拉刷新 第一步引入 import { Notify, Dialog, Image, List, PullRefresh } from 'vant' import Vue from 'vue' Vue.use(Image).use(List).use(PullRefresh) 第二步 <van-pull-refresh v-mode

  • vant之van-list的使用及踩坑记录

    第一步:要使用vant组件 安装好vant,npm i vant -S 第二步:在你要用到的地方js中引入 或者在src/main.js里面引入 import Vue from 'vue'; import { List } from 'vant'; Vue.use(List); 这里我引入的地方是我要用到的js文件中 第三步:在template中引用 第四步:js中重要代码 data(){ return{ content_list: [], loading: false,//加载状态 finis

  • 使用Vant框架list组件遇到的坑及解决

    目录 使用Vant框架list组件的坑 介绍 特性 聊一下使用list组件遇到的坑 vant中van-list的使用 使用Vant框架list组件的坑 介绍 Vant 是有赞前端团队开源的移动端组件库,于 2017 年开源,已持续维护 4 年时间. Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一. 特性 提供 60 多个高质量组件,覆盖移动端各类场景 性能极佳,组件平均体积不到 1kb(min+gzip) 单元测试覆盖率 90%+,提供稳定性保障 完善的

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

    目录 vant中list使用及首次加载触发两次 首次加载触发两次解决问题 vant中list列表组件使用 1. 基础结构 3.methods定义方法 4.调用api渲染页面 vant中list使用及首次加载触发两次 以下是list的基本使用方法,主要原理就是当页面数据小于offset这个高度的时候,就会触发load,在load里面需要调用接口发送下一页的数据.所以发送完毕后需要将设置分页的属性加一,并将获取到的新值push进接收数据的数组里,而不是直接赋值,如果直接赋值那么数组里就只有新值,之前

  • 通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题

    懒加载:也叫延迟加载,即在需要的时候进行加载,随用随载. 像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的白屏,即使做了loading也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时. 简单的说就是:进入首页不用一次加载过多资源造成用时过长!!! 懒加载的方式: import Vue from 'vue' import

  • vue 使用vant插件做tabs切换和无限加载功能的实现

    样例: 1.创建vue项目,不再详述 2.引入vant 之前用过很多插件做这个功能,但是效果都不尽人意,出现各种问题,直到遇到vant这个插件,完美的解决了这些小问题,如有问题,欢迎联系我 安装依赖 npm i vant -S 在main.js中引入 import Vant from 'vant'; import 'vant/lib/index.css'; Vue.use(Vant); 3.在页面中使用 官方写的比我写的好多了,大家可以借鉴,看源代码可能比官方给的文档更直观 官方文档 我在文件中

  • 在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程

    我是一位新的 Vim 编辑器用户.我通常使用 :vs ~/.vimrc 来加载 ~/.vimrc 配置.而当我编辑 .vimrc 时,我需要不重启 Vim 会话而重新加载它.在 Linux 或者类 Unix 系统中,如何在编辑 .vimrc 后,重新加载它而不用重启 Vim 呢? Vim 是自由开源并且向上兼容 Vi 的编辑器.它可以用来编辑各种文本.它在编辑用 C/Perl/Python 编写的程序时特别有用.可以用它来编辑 Linux/Unix 配置文件. ~/.vimrc 是你个人的 Vi

  • 解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题

    在项目中遇到后台数据还没有加载完毕,但是页面上调用了后台数据中的字段,这样就会报undefined. 例如:一进入页面直接回显数据. 我在created里面请求接口进行赋值 this.matterAll=[]; 会报accessItemName为undefined: 原因以及解决办法: 在上面data()中,我定义了matterAll:[],也就是空的数组, template中,我又直接用了this.matterAll[0],这个时候this.matterAll[0]=undefined,所以t

  • C#中通过反射将枚举元素加载到ComboBo的实现方法

    目录 一.前言 二.思路 三.上代码 一.前言 做过系统参数设置的同学们,肯定遇到过要提供一系列具有相同特点的选项供用户选择.最初级的做法是在窗体上增加一个下拉框控件,手工填写Items选项.然后运行时可以下拉选择.那如果有百八十个参数都是这种方式怎么办? 上述做法弊端很明显.那么如何灵活的实现这个需求呢? 二.思路 在代码中定义枚举类型,然后在窗体加载时,将枚举类型的元素(描述信息)加载到下拉框中,这样以后增加或修改了枚举元素后,下拉框中时刻保持的是最新的数据.再运用上反射机制,多个下拉框可以

  • Vue中使用import进行路由懒加载的原理分析

    目录 使用import进行路由懒加载的原理 (1)遵循规范 (2)调用时间 (3)本质 vue路由懒加载,使用import无法处理 解决 使用import进行路由懒加载的原理 首先我们来说说,import 和 require 的区别 node 编程中最重要的思想就是模块化,import 和 require 都是被模块化所使用. (1)遵循规范 require是 AMD规范引入方式 import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法 (2)调用时间 require是运行

  • vue组件实现首次加载就触发watch

    目录 组件首次加载就触发watch watch的初始立即执行 组件首次加载就触发watch 首次加载就触发watch需要修改其immediate属性为true,其默认值为false watch:{ "val":{ immediate:true,//首次加载的时候执行函数 deep:true,//深入观察数组值的变化, inputVal:function(){ } } } watch的初始立即执行 当 watch 一个变量的时候,初始化时并不会执行,如下面的例子,你需要在created的

  • elementui中使用el-tree控件懒加载和局部刷新

    目录 使用el-tree控件懒加载和局部刷新 懒加载 局部刷新 element-ui el-tree lazy懒加载局部刷新的问题 使用el-tree控件懒加载和局部刷新 懒加载 按照 elementui官方文档示例,效果图 template部分,需要结合 lazy 和 load 一起使用 <el-tree show-checkbox node-key="id" lazy :load="loadNode" :props="defaultProps&q

  • vue中el-autocomplete支持分页上拉加载功能

    目录 el-autocomplete使用 template 实现需求分析 1. 输入框为空时聚焦或失焦后又重新聚焦不会触发请求数据接口 2. 缓存上一次已查询的数据&搜索条件:blurArr.blurTxt 3.滚动加载指令(监听容器的scroll事件并进行防抖处理) 4. 分页加载 4.0 获取数据,并进行格式化 4.1 关闭加载圈 4.2 分页加载事件 4.3 清空输入框,重置上次记录的数据 4.4 选中时记录相关数据 数据展示不稳定问题 完整的 scss 文件 完整的 js 文件 总结 e

随机推荐