Vue?vant-ui框架實現上拉加載下拉刷新功能
下拉刷新效果:

知識點速記
基本用法
List通過loading和finished兩個變量控制加載狀態(tài),當組件滾動到底部時,會觸發(fā)load事件并將loading設置成true。此時可以發(fā)起異步操作并更新數據,數據更新完畢后,將loading設置成false即可。若數據已全部加載完畢,則直接將finished設置成true即可。
下拉刷新
List 組件可以與PullRefresh組件結合使用,實現下拉刷新的效果。
注意事項:
- v-model : 是否處于加載狀態(tài),加載過程中不觸發(fā)
load事件 - finished: 是否已加載完成,加載完成后不再觸發(fā)
load事件 - offset : 滾動條與底部距離小于 offset 時觸發(fā)
load事件 - loading-text加載過程中的提示文字
- finished-text加載完成后的提示文字
List有以下三種狀態(tài),理解這些狀態(tài)有助于你正確地使用List組件:
- 非加載中,
loading為false,此時會根據列表滾動位置判斷是否觸發(fā)load事件(列表內容不足一屏幕時,會直接觸發(fā)) - 加載中,
loading為true,表示正在發(fā)送異步請求,此時不會觸發(fā)load事件 - 加載完成,
finished為true,此時不會觸發(fā)load事件
在每次請求完畢后,需要手動將loading設置為false,表示加載結束
事件使用:@load方法
滾動條與底部距離小于 offset 時觸發(fā)
代碼實現
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>
<!-- 發(fā)票開具狀態(tài)(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 更新循環(huán)結束之后執(zhí)行延遲回調
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。解決上拉加載完畢后再下拉刷新就不會執(zhí)行上拉加載問題
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內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

