Vant list 與better-scroll與下拉重新整理(其實是上拉載入)
阿新 • • 發佈:2018-12-26
發現件事情,我好想把下拉重新整理和下拉載入搞反了,所以其實這篇記錄的是上拉載入,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的下拉重新整理
// 是否派發頂部下拉事件,用於下拉重新整理
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()還是和上面一樣的