- 按需引入
先安裝
npm install mint-ui -S // -S表示 --save
在文件中:
import Vue from 'vue'
import 'mint-ui/lib/style.css'
import { Loadmore } from 'mint-ui';
Vue.component(Loadmore.name, Loadmore);
<!-- !!!一定要給loadmore外層設置 overflow: scroll-->
<div style="overflow: scroll;">
<mt-loadmore
:top-method="loadTop"
:bottom-method="loadBottom"
:auto-fill="false"
:bottom-all-loaded="loadObj.allLoaded"
@top-status-change="handleTopChange"
@bottom-status-change="handleBottomChange"
ref="loadmore">
<!-- ##content 因爲content部分會出現沒數據情況,所以需要wrap這層設置高度將內容撐起來-->
<ul class="wrap" style="min-height: calc(100vh - 0.93rem - 64px);">
<li v-for="item in list" class="page-loadmore-listitem">{{ item }}</li>
</ul>
<div class="loadBlock" v-show="loadObj.allLoaded">
<span class="loadingWord">{{loadObj.loadingWord}}</span>
</div>
<!-- 自定義的刷新時樣式 -->
<div slot="top" class="mint-loadmore-top">
<span v-show="topStatus !== 'loading'" :class="{ 'is-rotate': topStatus === 'drop' }">↓</span>
<span v-show="topStatus === 'loading'">
<mt-spinner type="snake"></mt-spinner>
</span>
</div>
<!-- 自定義的加載時樣式 -->
<div slot="bottom" class="mint-loadmore-bottom">
<span v-show="bottomStatus !== 'loading'" :class="{ 'is-rotate': bottomStatus === 'drop' }">↑</span>
<span v-show="bottomStatus === 'loading'">
<mt-spinner type="snake"></mt-spinner>
</span>
</div>
</mt-loadmore>
</div>
- js部分
export default {
data() {
return {
loadObj: {
isShowOption: false, // 月份選擇popup
allLoaded: false, // 下拉加載全部加載
topStatus: '', // 上拉刷新的狀態變量,自定義樣式時用來控制顯隱
bottomStatus: '', // 下拉加載狀態變量,自定義樣式時用來控制顯隱
loadingWord: '正在加載',
},
pageBean: {
pageSize: 10, // 當前頁顯示條數
totalElements: 4, // 總條數
totalPages: 1, // 總頁數
currentPage: 0 // 當前頁
},
}
},
methods: {
// 存儲刷新的狀態
handleTopChange (status) {
this.loadObj.topStatus = status
},
// 存儲加載的狀態
handleBottomChange (status) {
this.loadObj.bottomStatus = status
},
// 下拉刷新
loadTop () {
setTimeout(() => {
this.pageBean.currentPage = 1 // 重置頁碼
this.getRankingListData() // 請求接口方法
this.$refs.loadmore.onTopLoaded('refresh')
}, 1500)
},
// 上拉加載
// 爲什麼要設置1.5秒延時:loadBottom是用戶開始上拉出發,1.5秒是用戶開始大約上拉鬆手的時間,避免一開始拉就請求接口
loadBottom () {
setTimeout(() => {
if (this.pageBean.totalPages === this.pageBean.currentPage) {
this.loadObj.loadingWord = '沒有更多的數據了'
this.loadObj.allLoaded = true
this.$refs.loadmore.onBottomLoaded()
return
}
this.pageBean.currentPage++ // 下拉一次頁數+1
let type = this.isSelectMonth ? 'month' : 'year'
this.getRankingListData( 'load') // 同一個請求接口方法,傳一個標識是用以判斷直接賦值還是拼接,拼接可以直接用concat()
this.$refs.loadmore.onBottomLoaded() // 結束動畫,可以放在接口回調中,實現數據請求回後再結束動畫
}, 1500)
}
}
}
- 上述代碼爲項目中實際應用到的部分代碼,不完整,下邊貼的是官方示例源碼,可供參考。
<template>
<div class="page-loadmore">
<h1 class="page-title">Pull up</h1>
<p class="page-loadmore-desc">在列表底部, 按住 - 上拉 - 釋放可以獲取更多數據</p>
<p class="page-loadmore-desc">translate : {{ translate }}</p>
<div class="loading-background" :style="{ transform: 'scale3d(' + moveTranslate + ',' + moveTranslate + ',1)' }">
translateScale : {{ moveTranslate }}
</div>
<div class="page-loadmore-wrapper" ref="wrapper" :style="{ height: wrapperHeight + 'px' }">
<mt-loadmore :top-method="loadTop" @translate-change="translateChange" @top-status-change="handleTopChange" :bottom-method="loadBottom" @bottom-status-change="handleBottomChange" :bottom-all-loaded="allLoaded" ref="loadmore">
<ul class="page-loadmore-list">
<li v-for="item in list" class="page-loadmore-listitem">{{ item }}</li>
</ul>
<div slot="top" class="mint-loadmore-top">
<span v-show="topStatus !== 'loading'" :class="{ 'is-rotate': topStatus === 'drop' }">↓</span>
<span v-show="topStatus === 'loading'">
<mt-spinner type="snake"></mt-spinner>
</span>
</div>
<div slot="bottom" class="mint-loadmore-bottom">
<span v-show="bottomStatus !== 'loading'" :class="{ 'is-rotate': bottomStatus === 'drop' }">↑</span>
<span v-show="bottomStatus === 'loading'">
<mt-spinner type="snake"></mt-spinner>
</span>
</div>
</mt-loadmore>
</div>
</div>
</template>
<style>
.loading-background, .mint-loadmore-top span {
-webkit-transition: .2s linear;
transition: .2s linear
}
.mint-loadmore-top span {
display: inline-block;
vertical-align: middle
}
.mint-loadmore-top span.is-rotate {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
.page-loadmore .mint-spinner {
display: inline-block;
vertical-align: middle
}
.page-loadmore-desc {
text-align: center;
color: #666;
padding-bottom: 5px
}
.page-loadmore-desc:last-of-type,
.page-loadmore-listitem {
border-bottom: 1px solid #eee
}
.page-loadmore-listitem {
height: 50px;
line-height: 50px;
text-align: center
}
.page-loadmore-listitem:first-child {
border-top: 1px solid #eee
}
.page-loadmore-wrapper {
overflow: scroll
}
.mint-loadmore-bottom span {
display: inline-block;
-webkit-transition: .2s linear;
transition: .2s linear;
vertical-align: middle
}
.mint-loadmore-bottom span.is-rotate {
-webkit-transform: rotate(180deg);
transform: rotate(180deg)
}
</style>
<script>
import Vue from 'vue'
import 'mint-ui/lib/style.css'
import NbLoading from '@/components/public/NbLoading'
import { Loadmore } from 'mint-ui'
Vue.component(Loadmore.name, Loadmore)
export default {
data() {
return {
list: [],
allLoaded: false,
bottomStatus: '',
wrapperHeight: 0, topStatus: '',
//wrapperHeight: 0,
translate: 0,
moveTranslate: 0
};
},
methods: {
handleBottomChange(status) {
this.bottomStatus = status;
},
loadBottom() {
setTimeout(() => {
let lastValue = this.list[this.list.length - 1];
if (lastValue < 40) {
for (let i = 1; i <= 10; i++) {
this.list.push(lastValue + i);
}
} else {
this.allLoaded = true;
}
this.$refs.loadmore.onBottomLoaded();
}, 1500);
},
handleTopChange(status) {
this.moveTranslate = 1;
this.topStatus = status;
},
translateChange(translate) {
const translateNum = +translate;
this.translate = translateNum.toFixed(2);
this.moveTranslate = (1 + translateNum / 70).toFixed(2);
},
loadTop() {
setTimeout(() => {
let firstValue = this.list[0];
for (let i = 1; i <= 10; i++) {
this.list.unshift(firstValue - i);
}
this.$refs.loadmore.onTopLoaded();
}, 1500);
},
},
created() {
for (let i = 1; i <= 20; i++) {
this.list.push(i);
}
},
mounted() {
this.wrapperHeight = document.documentElement.clientHeight - this.$refs.wrapper.getBoundingClientRect().top;
}
};
</script>