Vant list 与better-scroll与下拉刷新(其实是上拉加载)

发现件事情,我好想把下拉刷新和下拉加载搞反了,所以其实这篇记录的是上拉加载,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改成
    //即可。
 
</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()还是和上面一样的

你可能感兴趣的:(Vue实践)