Vue vant-ui框架实现上拉加载下拉刷新功能

目录
  • 知识点速记
    • 基本用法
    • 下拉刷新
    • 代码实现
      • 1.页面布局
      • 2.样式
      • 3.方法

下拉刷新效果:

知识点速记

基本用法

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

下拉刷新

List 组件可以与PullRefresh组件结合使用,实现下拉刷新的效果。

注意事项:

  • v-model : 是否处于加载状态,加载过程中不触发load事件
  • finished: 是否已加载完成,加载完成后不再触发load事件
  • offset : 滚动条与底部距离小于 offset 时触发load事件
  • loading-text加载过程中的提示文字
  • finished-text加载完成后的提示文字

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

  • 非加载中,loadingfalse,此时会根据列表滚动位置判断是否触发load事件(列表内容不足一屏幕时,会直接触发)
  • 加载中,loadingtrue,表示正在发送异步请求,此时不会触发load事件
  • 加载完成,finishedtrue,此时不会触发load事件

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

事件使用:@load方法

滚动条与底部距离小于 offset 时触发

代码实现

1.页面布局

<template>
  <div class="myOrder">
    <!--公共头部组件-->
    <nav-bar-top :titleText="titleName" :arrowTrue="arrowTrue"></nav-bar-top>
   <!--主体部分-->
    <div class="tabMain" style="margin-top:0">
      <div v-if="noData" class="p30 text-center fontSize30">
         <van-empty class="custom-image" :image="zwdd"/>
      </div>
      <van-pull-refresh v-model="isLoading" @refresh="onRefresh" class="content" success-text="刷新成功">
        <!-- 加载 -->
        <van-list v-if="contractData.length>0" v-model="loading" :finished="finished" :immediate-check="false" finished-text="我也是有底线的"
          @load="onLoad" :offset="10">
          <van-row class="m30 p30 capaIttem" v-for="item in contractData" :key="item.orderId">
            <van-col span="24" class="fontSize30">
              <div class="focus-con">
                <!-- ellipsis-orderNumber -->
                <div class="focus-title">
                  <span class="color3 van-ellipsis">合同编号:{{item.contractNumber}}</span>
                  <!-- <span class="color3 van-ellipsis">{{item.outsideContractId?'订单':'合同'}}编号:{{item.contractNumber}}</span> -->
                  <!-- <img src="../../assets/index/VIPICO.png" class="vipIcon pl20"> -->
                </div>
                <!-- 发票开具状态(0:待申请,1:待审核,2:审核未通过,3:审核已通过) -->
                <div>
                  <van-tag :text-color="item.status=='0'?'#FF9133':item.status=='1'?'#4972FF':item.status=='2'?'#F1403C':'#00CE80'" class="tagStyle">
                    {{item.status=="0"?"待申请":item.status=="1"?"待审核":item.status=="2"?"审核未通过":"审核通过"}}
                  </van-tag>
                </div>
              </div>
            </van-col>
            <van-col span="24" class="mt10">
              <div class="capa-box">
                <div class="focus-title" >
                  <span class="color3 shipName fontSize32">{{item.userName}}</span>
                </div>
              </div>
              <div class="capa-box">
                <div class="color6 flex align-items fontSize24 van-ellipsis ellipsis-content">
                  <img src="../../assets/img/huo.png" class="huoIcon mr5">
                  {{item.unlimitedLoading&&item.unlimitedLoading=="1"?"随船装/":""}}
                  <span class="" v-if="item.cargoWeight">{{item.cargoWeight}}吨/</span>
                  <span class="van-ellipsis">{{item.cargoName?item.cargoName:""}}</span>
                </div>
              </div>
            </van-col>
            <van-col span="24" class="capa-body">
              <div class="capa-con fontSize28">
                <div class="content-left">
                  <img src="../../assets/index/zhuang.png" alt="" class=" mr5">
                  <span>{{item.loadingPort}}</span>
                </div>
                <img src="../../assets/index/arrows.png" class="capa-jt">
                <div class="content-right">
                  <img src="../../assets/index/xie.png" alt="" class=" mr5">
                  <span>{{item.arrivePort}}</span>
                </div>
              </div>
              <div class="capa-time mt10">
                <div class="capa-time-left">
                  <div class="time-img">
                    <img src="../../assets/index/time.png" class="capaImg">
                    <span class="timeTXT fontSize28 pl10">装货时间</span>
                  </div>
                  <div class="timeColor fontSize34 mt10 timeError">
                    {{item.loadingTime?item.loadingTime:"暂无"}}
                  </div>
                </div>
                <div style="height:50px;border-left:1px solid #E1E1E1"></div>
                <div class="capa-time-right">
                  <div class="time-img priceContent">
                    <img src="../../assets/index/money.png" class="capaImg">
                    <span class="timeTXT fontSize28 pl10">合同金额</span>
                  </div>
                  <div>
                    <div class="timeColor fontSize34 mt10 floatRight">
                       <span v-if="item.contractAmount">
                         {{item.priceType=="0"?item.contractAmount+"元":item.priceType=="1"?item.contractAmount+"元/吨":item.contractAmount+"元"}}
                       </span>
                       <span v-else>暂无报价</span>
                    </div>
                  </div>
                </div>
              </div>
            </van-col>
            <van-col style="width:100%" class="mt20">
              <div class="flex flex-end">
                  <van-button plain type="info" class="borderRaduis" size="small" @click="handleLook(item)">查看合同</van-button>
                  <van-button v-show="item.status=='2'" plain type="info ml20" class="borderRaduis" size="small" @click="handleFail(item,item.invoiceId)">失败原因</van-button>
                  <van-button class="ml20 borderRaduis" color="#024ee0" type="info" size="small">{{item.status=='2'?'重新申请':'申请开票'}}</van-button>
              </div>
            </van-col>
          </van-row>
        </van-list>
      </van-pull-refresh>
    </div>
</div>
</template>

2.样式

.myOrder{
  height: 100vh;
  overflow-y: auto;
}
::v-deep.van-cell {
  font-size: 14px;
}
.capaIttem {
  box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.06);
  border-radius: 24px;
  background: #fff;
  position: relative;
}
::v-deep.van-cell {
  padding: 10px 0;
}
::v-deep.van-cell {
  font-size: 40px;
  line-height: 40px;
  font-size: 30px;
}

::v-deep.van-field__left-icon .van-icon {
  font-size: 30px;
}
::v-deep.van-tag {
  font-size: 24px;
  line-height: 40px;
}
::v-deep.van-button--small {
  height: 60px;
  font-size: 24px;
}
::v-deep.van-tabs--line .van-tabs__wrap {
  height: 88px;
}
::v-deep.van-tab {
  font-size: 30px;
}

.searchBtnFixed {
  position: fixed;
  top: 0;
  left: 80px;
  height: 92px;
  line-height: 92px;
  z-index: 1000;
  width: 86%;
  overflow: hidden;
}
::v-deep.van-search {
  position: absolute;
  top: -8px;
  // padding: 13px;
  width: 100%;
}
::v-deep.van-search__content {
  background: #eeeeee;
  border-radius: 16px;
  padding: 5px 10px;
}
.focusSearch ::v-deep.van-icon-clear {
  padding-right: 160px;
}
// 搜索
.onSearch {
  position: absolute;
  right: 50px;
  top: 28px;
  font-size: 30px;
  height: 36px;
  line-height: 36px;
  border-left: 1px solid #cccccd;
  padding-left: 30px;
  color: #024ee0;
}
// 新增
.focus-con {
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid #ebedf0;
  padding-bottom: 20px;
}
.capa-title {
  border-bottom: 1px solid #ebedf0;
  padding-bottom: 20px;
  display: flex;
  align-items: center;
}
.focus-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
}
.vipIcon {
  width: 72px;
  height: 34px;
}
.capa-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 10px;
}
.capa-body {

  background: #f5f8ff;
  border-radius: 0.13333rem;
  padding: 0.33333rem;
}
.capa-con {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
}
.content-left,
.content-right {
  display: flex;
  justify-content: space-between;
  align-items: center;
  img {
    width: 0.5rem;
    height: 0.5rem;
  }
}
.capa-time {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.time-img {
  display: flex;
  align-items: center;
}
.capaImg {
  width: 30px;
}
.timeColor {
  font-weight: 700;
  color: #024ee0;
}
.order-group {
  display: flex;
  align-items: center;
}
.ellipsis-orderNumber{
  span{
    display: inline-block;
    width: 310px;
  }
}
.ellipsis-txt {
  display: inline-block;
  max-width: 200px;
  text-align: start;
}
.shipName {
  font-weight: 600;
  display: flex;
  align-items: center;
}
.orderNameWidth{
  max-width: 220px;
}
.ellipsis-content{
  width: 400px;
}
.priceContent{
  display: flex;
  justify-content: flex-end;
}
.floatRight{
  float: right;
}
.borderRaduis {
  border-radius: 10px;
  height: 56px;
  .van-button__text {
    font-size: 26px;
  }
}
.huoIcon{
  width: 26px;
  height: 26px;
}
.tagStyle{
  background-color: #fff !important;
}
.contactTel {
  width: 90%;
  border-radius: 10px;
}
.popup-header{
  height: 100px;
  text-align: center;
  color:#fff;
  background: #024EE0;
  line-height: 100px;
}
.contactTel ::v-deep.van-popup__close-icon--top-right{
  top:26px !important;
  color:#fff !important;
}
.popup-box{
  margin:60px 50px 30px;
}
.popup-btn{
  width: 100%;
  border-radius: 20px;
  font-size: 36px;
}
.popupTitle {
  box-sizing: border-box;
  padding: 35px 0 61px 0;
  font-size: 32px;
  color: #333333;
  font-weight: 500;
}
.imgContent {
  display: flex;
  align-items: center;
  justify-content: space-around;
  flex-wrap: wrap;
  margin-bottom: 30px;
  padding: 0 10px;
  li {
    width: 125px;
    height: 125px;
    margin-bottom: 37px;
    background-color: black;
    margin-right: 25px;
  }
  li:nth-of-type(4n) {
    margin-right: 0;
  }
}

3.方法

data数据定义:

data() {
    return {
      zwdd:require("../../assets/img/zwdd.png"),
      titleName: "我要开票",
      arrowTrue: true,
      page: 1,
      pageSize: 10,
      isLoading: false,
      loading: false,
      finished: false,
      noData: false,
      contractData: [],
      timer:null,
    };
  },

加载更多方法onLoad:

// 加载更多
    onLoad() {
      this.loading = true;
      this.timer = setTimeout(() => {
        this.page++;
        this.getInvoicingContractListFun();
      }, 1000);
    },

下拉刷新方法onRefresh:下拉刷新调用接口,并且页数=1

    // 刷新
    onRefresh() {
      this.isLoading = true;
      this.page = 1;
      if (this.contractData.length == 0) {
        this.isLoading = false;
      }
      this.getInvoicingContractListFun();
    },

处理数据列表方法getInvoicingContractListFun:

调用接口,传递相应的参数,获取到数据,去判断处理数据数据的加载,数据合并操作,利用定义的loading、finished、isLoading控制数据上拉数据加载。

    // 数据列表方法
    getInvoicingContractListFun() {
      let params = {
        carrierUserId: this.id,
        pageNum: this.page,
        pageSize: this.pageSize
      };
      getInvoicingContractList(params)
        .then(res => {
          if (res.code == 200) {
            if (this.contractData.length > 0) {
              this.noData = false;
              //当请求前有数据时 第n次请求
              if (this.loading) {
                // 上拉加载
                this.contractData = this.contractData.concat(res.data.records); //上拉加载新数据添加到数组中
                this.$nextTick(() => {
                  //在下次 DOM 更新循环结束之后执行延迟回调
                  this.loading = false; //关闭上拉加载中
                });
                if (res.data.records.length == 0) {
                  //没有更多数据
                  this.finished = true; //上拉加载完毕
                }
              }
              if (this.isLoading) {
                //关闭下拉刷新
                this.isLoading = false; //关闭下拉刷新中
                this.contractData = res.data.records; //重新给数据赋值
                if (this.finished) {
                  //如果上拉加载完毕为true则设为false。解决上拉加载完毕后再下拉刷新就不会执行上拉加载问题
                  this.finished = false;
                }
              }
            } else {
              this.noData = false;
              this.loading = false;
              this.isLoading = false;
              this.finished = false;
              //当请求没有数据时 第一次请求
              if (res.data.records.length == 0) {
                this.noData = true;
              } else {
                this.contractData = res.data.records;
              }
            }
          } else {
            this.$toast(res.msg);
          }
        })
        .catch(error => {});
    },

created中调用方法获取数据

created(){
    //方法调用
    this.getInvoicingContractListFun();
}

最后在beforeDestroy生命周期清除定时器

beforeDestroy() {
    clearTimeout(this.timer);
    this.timer = null;
}

到此这篇关于Vue vant-ui框架实现上拉加载下拉刷新功能的文章就介绍到这了,更多相关Vue vant-ui内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue+vant-UI框架实现购物车的复选框全选和反选功能

    购物车页面的设计图 商品的列表 代码: <ul v-if="shoppingListData.rows.length"> <li v-for="(item,index) in shoppingListData.rows" :key="index" > <van-checkbox :value="item.goods_id" v-model="item.isChecked" ch

  • Vue vant-ui使用van-uploader实现头像上传功能

    效果图: 项目中是使用有赞vant-ui框架实现的头像上传替换功能 代码布局结构: <van-row class="sendInfo"> <van-col span="24" class="flex colorf topInfo p20"> <!--左边头像部分--> <van-uploader :after-read="afterCard" :before-read="be

  • vue 公共列表选择组件,引用Vant-UI的样式方式

    此组件用于公共选择组件.引用Vant UI 作为样式 特性: 1.支持动态.静态数据源. 2.支持分页加载. 3.支持模糊搜索. 4.支持单选.多选. 组件源码: <template> <div class="gn-PubSelect"> <van-action-sheet v-model="inShow"> <div class="gn-PubSelect-main" :style="{'he

  • vue基于vant实现上拉加载下拉刷新的示例代码

    前言 普遍存在于各种app中的上拉加载下拉刷新功能大家都不陌生吧,一般来说,在数据量比较大的情况下,为了更快的渲染和给用户更好的观感体验,我们会将数据做分页处理,让其批量加载,这样一来,在渲染速度上,能给用户一个比较好的体验效果.话说回来,分页处理,也就是我们今天要讲的上拉加载和下拉刷新. 实现思路 下拉刷新: 请求接口赋完值后,将接口返回数据长度与总条数进行比较控制加载不加载的状态,在下拉刷新方法中定义起始页码为第一页,调整加载的状态为false,最后调用请求数据的接口方法,做适当轻提示即可.

  • Vue uni-app框架实现上拉加载下拉刷新功能

    目录 实现上拉加载更多 优化 实现下拉刷新 实现上拉加载更多 打开项目根目录中的pages.json配置文件,为subPackages分包中的商品goods_list页面配置上拉触底的距离: "subPackages": [ { "root": "subpkg", "pages": [ { "path": "goods_detail/goods_detail", "style&

  • Vue vant-ui框架实现上拉加载下拉刷新功能

    目录 知识点速记 基本用法 下拉刷新 代码实现 1.页面布局 2.样式 3.方法 下拉刷新效果: 知识点速记 基本用法 List通过loading和finished两个变量控制加载状态,当组件滚动到底部时,会触发load事件并将loading设置成true.此时可以发起异步操作并更新数据,数据更新完毕后,将loading设置成false即可.若数据已全部加载完毕,则直接将finished设置成true即可. 下拉刷新 List 组件可以与PullRefresh组件结合使用,实现下拉刷新的效果.

  • Android ListView实现上拉加载下拉刷新和滑动删除功能

    最近项目需要用到可以滑动删除并且带有上拉加载下拉刷新的Listview,查阅了一些资料,大多都是在SwipeMenuListView的基础上去添加头部和底部View,来扩展上拉加载和下拉刷新的功能,不过需要手动的去绘制UI及处理一些动画效果.用起来也不是特别方便.刚好项目中用到PulltorefreshLibrary库,就尝试着扩展了一个PullToRefreshSwipeMenuListView类来实现需求.先看一下效果: 实现步骤 一.组合Pulltorefresh与SwipeMenuLis

  • 微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)

    微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一) 页面缓存的设置优化了页面加载,减少了频繁的调取接口,使用户在断网的情况下有更好的体验. 每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync).wx.getStorage(wx.getStorageSync).wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置.获取和清理.本地缓存最大为10MB. 注意: localSt

  • Android自定义listview布局实现上拉加载下拉刷新功能

    listview实现上拉加载以及下拉刷新的方式有很多.下面是我写的一种自定义的布局,复用性也比较的强.首先就是继承的listview的自定义view.   AutoListView.Java: package com.example.mic.testdemo.view; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.os.Bu

  • mescroll.js上拉加载下拉刷新组件使用详解

    本文实例为大家分享了上拉加载下拉刷新组件mescroll.js的具体代码,供大家参考,具体内容如下 附上链接地址http://www.mescroll.com/api.html#NPM,手机端和浏览器都能够使用,唯一推荐: 使用过程中要注意这些问题http://www.mescroll.com/qa.html: 使用注意事项: 1.引入的时候出问题及时看官方给出的解决方案(基本上都必须看): 2.react中一定要在dom渲染之后的方法(didMount)中初始化,因为这个需要拿到dom对象:

  • Android通过XListView实现上拉加载下拉刷新功能

    本文实例为大家分享了XListView实现上拉加载下拉刷新的具体代码,供大家参考,具体内容如下 ## 导入XListVIew第三方库文件.通过LinkedList将刷新数据插入到集合头部,将加载的数据放入集合尾部 ## private Context context; private View view; private String path; private XListView xlv; private LinkedList<Data> listData; private Handler

  • vue.js整合vux中的上拉加载下拉刷新实例教程

    前言 Vux 是基于 Vue 和 Weui 开发的手机端页面 UI 组件库,开发初衷是满足公司的微信端表单需求,因为第三方的调查问卷表单系统在手机上实在比较丑(还是 PC 那一套样式适配了大小而已).于是用 vue 重构了表单组件,后来一发不可收拾把其他常用组件也一并开发了. 相比于 React 还是更喜欢用 Vue ,除了目前社区组件不多,周边构建工具还是比较完善的(作者也特别勤奋). 下面话不多说了,来一看看详细的介绍吧. 先上图 创建项目 使用vue-cli 创建一个vue项目 安装vux

  • 微信小程序(六):列表上拉加载下拉刷新示例

    1.列表(本部分内容出入官方文档) 对于这个功能,微信小程序中并没有提供类似于Android中listview性质的控件,所以我们需要使用 wx:for 控制属性绑定一个数组,用数组中各项的数据重复渲染该组件,来达到列表的效果. <view wx:for="{{array}}"> {{index}}: {{item.message}} </view> Page({ data: { array: [{ message: 'foo', }, { message: '

随机推荐