發現件事情,我好想把下拉刷新和下拉加載搞反了,所以其實這篇記錄的是上拉加載,emmm。。
先是用了vant的LIst下拉刷新,然後發現better-scroll中這個插件沒有用,然後自己寫了個監聽!最後發現一篇文章有封裝scroll中下拉刷新!這個過程也是莫名其妙了。
1、首先是用了Vant的List實現
Vant List官網
這部分就是官網的例子修改了點。注意一個參數:immediate-check 是否在初始化時立即執行滾動位置檢查,默認是true,就在created的時候就執行一次onLoad加載,如果你的代碼不需要一開始就執行onLoad,設置爲false.
<template>
<van-list v-model="loading" :finished="finished" @load="onLoad" :loading-text="loadText">
//基本用法就這個樣子了
//這裏就放自己的數據了,隨便弄點數據吧!
<div v-for="goods in goodsInfo">
<delete-goods-list :goods="goods"></delete-goods-list>
</div>
</van-list>
</template>
<script type="text/ecmascript-6">
//設置一個每次加載的數據個數
const loadNumUp = 5;
data() {
return {
loading: false,
finished: false,
loadText:'加載中…',
pageNum:1,
upGoodsInfo: [],
}
},
methods: {
//只要檢測到你在下拉,默認距離底部300px時就刷新
onLoad() {
console.log('上拉加載');
// 異步更新數據,要看效果,官網的例子是通過setTimeOut進行延時模擬異步更新,把延時時間調大點效果就很明顯。
//這裏我是向服務器發請求獲得的數據,服務器端是分頁的。
let postInfoUp = {
"data": {
//參數爲每次訪問的個數和頁數
"limit": loadNum,
"page": ++this.pageNum,
}
};
this.$api.Goods.getAllGoods(postInfoUp)
.then(res => {
if (res.data.code === 200) {
let re = res.data.data.list;
if (re.length !== 0) {
//新增數據拼接在後面
this.upGoodsInfo = this.upGoodsInfo.concat(ss);
}
// 加載狀態結束
this.loadingUp = false;
// 數據全部加載完成
if (this.upGoodsInfo.length >= this.totalNumUp) {
this.finishedUp = true;
this.loadText = "加載完成";
console.log('沒數據要加載了')
}
}else{
this.finished = true;
}
});
},
}
</script>
注意事項:
vant中的list實際上監聽的是scroll事件,當你上拉時,觸發onLoad事件,並將loading設置爲true。
但這個組件不適用於better-scroll,如果你整個頁面用了better-scroll,那麼你滾動要監聽的事件是touchstart和touchend,因爲它模擬的就是手機端手勢,監聽web端的滾動scroll是沒有任何變化的。
2、在better-scroll下,上拉加載
這篇文章在vue下將better-scroll重新封裝,除了原本良好的用戶體驗,還包含下拉刷新,上拉加載功能。
當 better-scroll 遇見 Vue
但是,我寫的時候並沒有看到這個,宛如一個瞎子 ̄ω ̄~
好吧,既然list不監聽touchstart和touchend,那就自己寫吧。
<div >
<div v-for="goods in goodsInfo">
<delete-goods-list :goods="goods"></delete-goods-list>
</div>
//加個加載提示,
<p v-show="showLoad">加載中……}</p>
//要是想用LIst的提示,把這裏最外層的div改成
//<van-list v-model="loading" loading-text="加載中……" >即可。
</div>
data() {
return {
goodsInfo: [],
loading: false,
finished: false,
showLoad:false,
}
} ,
//監聽
mounted() {
let startx, starty;
let self = this;
//手指接觸屏幕
document.addEventListener('touchstart', (e) => {
startx = e.touches[0].pageX;
starty = e.touches[0].pageY;
});
//手指離開屏幕
document.addEventListener("touchend", function (e) {
let endx = e.changedTouches[0].pageX;
let endy = e.changedTouches[0].pageY;
let direction = getDirection(startx, starty, endx, endy);
//當手勢向上滑動,加載
if (direction === 1) {
self.showLoad = true;//顯示加載提示
console.log("向上滑動!", self.finished);
if (self.finished === false) {
self.loading = true;
self.onLoad();
self.$refs.mScroll._initScroll();
}
}
});
},
methods: {
onLoad() {
if (this.loading === true && this.finished === false) {
// 異步更新數據,跟用list時的onLoad中代碼是一樣的
....
// 加載狀態結束
this.loading = false;
this.showLoad = false;
......
}
}
}
getDirection獲取方向,這個也是搬運呀,原博客。
export function getDirection(startx, starty, endx, endy) {
var angx = endx - startx;
var angy = endy - starty;
var result = 0;
//如果滑動距離太短
if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
return result;
}
var angle = getAngle(angx, angy);
//1:向上; 2:向下; 3:向左; 4:向右
//這裏利用的角度,手勢是向上,列表向下滑動。即end在start上方,
//此時angx爲正,angy爲負,位於第四象限,限定<-45即是垂直方向。
if (angle >= -135 && angle <= -45) {
result = 1;
} else if (angle > 45 && angle < 135) {
result = 2;
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 3;
} else if (angle >= -45 && angle <= 45) {
result = 4;
}
return result;
};
function getAngle(angx, angy) {
return Math.atan2(angy, angx) * 180 / Math.PI;
};
3、用封裝了better-scroll的上拉加載
實現加載應該修改pullup,然而我改的下拉刷新(pulldown),湊合看吧。。。。
按照這篇文章進行配置:當 better-scroll 遇見 Vue
// 是否派發頂部下拉事件,用於下拉刷新
if (this.pulldown) {
this.scroll.on('touchend', (pos) => {
// 下拉動作
if (pos.y > 50) {
this.$emit('pulldown')
}
})
}
...
上面的這部分代碼用下面的代碼替代
if (this.pulldown) {
console.log('pulldown');
let startx, starty;
let self = this;
//手指接觸屏幕
document.addEventListener('touchstart', (e) => {
startx = e.touches[0].pageX;
starty = e.touches[0].pageY;
});
//手指離開屏幕
document.addEventListener("touchend", function (e) {
let endx = e.changedTouches[0].pageX;
let endy = e.changedTouches[0].pageY;
let direction = getDirection(startx, starty, endx, endy);
//當手勢向上滑動,加載
if (direction === 1) {
//向父組件發送 下拉請求,執行相應函數
self.$emit('pulldown');
}
});
}
頁面HTML
<template>
<div class="deleteGoods">
<scroll class="vertical-fixed"
:data="goodsInfo"
:pulldown="pulldown" @pulldown="onLoad" >
<div class="vertical-fixed-wrapper" >
<div v-for="goods in goodsInfo">
<delete-goods-list :goods="goods"></delete-goods-list>
</div>
<!--這裏加height: 0 ,是因爲會出現當display:none時還是佔據了空間,
所以設置高度爲0,margin-top: 10px是爲了首次加載的時候,動畫與top有距離-->
<div v-show="showLoad" style="height: 0; margin-top: 10px">
<van-loading type="spinner" style="margin: 0 auto" ></van-loading>
</div>
</div>
</scroll>
</div>
</template>
//onload()還是和上面一樣的