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

本文详细介绍了在Vue项目中实现上拉加载更多和下拉刷新功能的方法,包括使用Vant UI组件库的List组件及在Better Scroll环境下自定义触摸事件实现。探讨了不同场景下的实现技巧和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发现件事情,我好想把下拉刷新和下拉加载搞反了,所以其实这篇记录的是上拉加载,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()还是和上面一样的
### CarStatusBar 下拉实现及相关问题解决方案 #### 1. 利用 `onPopupScroll` 实现下拉菜单滚动监听 对于 CarStatusBar 的下拉功能,如果需要实现在滚动过程中触发某些逻辑操作(如加载更多数据或检测是否到达底部),可以借鉴 `onPopupScroll` 事件的处理方法。通过该事件能够实时获取到下拉菜单的滚动状态,并进一步判断是否已达到容器底部[^1]。 以下是基于此原理的一个简单代码示例: ```javascript function handleOnPopupScroll(event) { const { scrollTop, scrollHeight, clientHeight } = event.target; if (scrollTop + clientHeight >= scrollHeight - 5) { console.log('已经接近或者达到了下拉菜单底部'); loadMoreData(); // 调用加载更多函数 } } // 绑定滚动事件 document.querySelector('.car-status-bar-dropdown').addEventListener('scroll', handleOnPopupScroll); ``` --- #### 2. C# WinForm 中 ComboBox 下拉选项不显示文本的问题解决 在开发 Windows Forms 应用程序时,可能会遇到类似于 CarStatusBar 的控件——ComboBox,在其 DropDownStyle 设置为 DropDownList 后发现选项为空白的情况。这种现象通常由以下几个原因引起: - 数据绑定未正确设置; - 字体颜色背景色冲突; - 控件样式被意外修改。 针对这些问题的具体修复措施如下[^2]: - 确认 DataSource 已经成功赋值给 ComboBox。 - 使用 ItemAppearance 属性调整字体大小和颜色以提高可读性。 - 如果涉及多线程更新 UI,则需调用 Invoke 方法确保主线程安全访问。 --- #### 3. Vue 移动端动态加载分页支持 当构建移动端应用并希望实现类似 CarStatusBar 功能时,可能需要用到 vue 或 uni-app 提供的支持机制。例如 UniApp 结合 uView 框架提供了完整的上下滑动交互体验;而对于 H5 页面来说也可以考虑采用 Vant ListBetter Scroll 插件完成相似效果[^3]。 下面是一个简单的例子展示如何利用 onReachBottom 来模拟触底行为从而请求新一批次的数据项: ```html <template> <div id="app"> <ul v-if="items.length > 0"> <li v-for="(item,index) in items" :key="index">{{ item }}</li> </ul> <button @click="loadMore">Load More...</button> </div> </template> <script> export default { data() { return { items: [], page: 1, }; }, methods: { async fetchData(pageNumber){ const response = await fetch(`https://api.example.com/data?page=${pageNumber}`); this.items.push(...await response.json()); } loadMore(){ this.page +=1 ; this.fetchData(this.page); } } mounted(){ this.fetchData(1); // 初始化加载第一页的内容 } } </script> ``` --- #### 4. Excel 导出中的下拉列表长度限制规避策略 假如您的业务场景涉及到将大量预定义条目作为单元格内的选择框呈现出来的话,那么需要注意 POI 默认只允许最多容纳不超过 255 表单项的情形。对此类特殊需求则可通过自定义 XML 文件结构的方式来绕过上述约束条件[^4]。 主要步骤包括但不限于创建扩展名名为 `.xlsx` 的 ZIP 归档文件夹内部新增 `<sheetName>/dropdowns.xml` 定义节点以及关联关系表记录等复杂过程... --- ###
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值