发现件事情,我好想把下拉刷新和下拉加载搞反了,所以其实这篇记录的是上拉加载,emmm。。
先是用了vant的LIst下拉刷新,然后发现better-scroll中这个插件没有用,然后自己写了个监听!最后发现一篇文章有封装scroll中下拉刷新!这个过程也是莫名其妙了。
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是没有任何变化的。
这篇文章在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改成
//即可。
</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;
};
实现加载应该修改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()还是和上面一样的