uniapp自定义scroll-view的下拉刷新公共组件

  • 如果使用组件后页面无法滚动,可试试在pages.json文件中使用了refresh组件的页面中配置"disableScroll": true来禁用页面级滚动
    {
    "path" : "使用了refresh组件的页面路径",
    "style" : {
        "navigationBarTitleText":"使用了refresh组件的页面标题",
         // 使用下拉刷新组件的页面 设置不能页面滚动 否则ios下拉有问题
        "disableScroll": true    
    }
    }

使用 :

<refresh @onRefresh="">
     此处是你自己的列表内容
</refresh>

 源码

<template>
	<scroll-view style="height: 100%;"
				:scroll-y="allow_scroll_y"
				@scroll="scroll">
		<view class="refresh-moudle"
			@touchstart="touchStart($event)" 
			@touchmove="touchMove($event)" 
			@touchend="touchEnd($event)" 
			:style="{transform: 'translate3d(0,' + top + 'px, 0)'}">
		  <view class="pull-refresh">
			<slot name="pull-refresh">
			  <view class="down-tip" v-if="dropDownState==1">
				<image v-if="dropDownInfo.downImg" class="down-img" :src="dropDownInfo.downImg"></image>
				<view class="down-text">{{dropDownInfo.downText}}</view>
			  </view>
			  <view class="up-tip" v-if="dropDownState==2">
				<image v-if="dropDownInfo.upImg" class="up-img" :src="dropDownInfo.upImg"></image>
				<view class="up-text">{{dropDownInfo.upText}}</view>
			  </view>
			  <view class="refresh-tip" v-if="dropDownState==3">
				<image v-if="dropDownInfo.refreshImg" class="refresh-img" :src="dropDownInfo.refreshImg"></image>
				<view class="refresh-text">{{dropDownInfo.refreshText}}</view>
			  </view>
			</slot>
		  </view>
		  <slot></slot>
		</view>
	</scroll-view>
</template>

<script>
	export default {		
		data () {
			return {
			  defaultOffset: 80, // 下拉偏移高度, 如果要改建议相应的修改.releshMoudle的margin-top和.down-tip, .up-tip, .refresh-tip的height
			  top: 0,
			  startY: 0,
			  isDropDown: false, // 是否下拉
			  isRefreshing: false, // 是否正在刷新
			  dropDownState: 1, // 显示1:下拉可以刷新, 2:松开立即刷新, 3:正在刷新数据中...
			  dropDownInfo: {
				downText: '下拉可以刷新',
				downImg: '/static/components/refresh/xiangxia.png',
				upText: '松开立即刷新',
				upImg: '/static/components/refresh/xiangxia.png',
				refreshText: '正在刷新数据...',
				refreshImg: '/static/components/refresh/loading.png'
			  },
			  scrollTop: 0,
			  allow_scroll_y: true,//解决因ios环境下scrollview的scrolltop可下拉为负数带来的体验问题
			  allowTouchMove: true //控制是否允许touchMove事件
			}
		},
		methods: {
			scroll: function(e) {
				this.$nextTick(function() {
					this.scrollTop = e.detail.scrollTop
				});
			},
			/**
			 * 触摸开始,手指点击屏幕时
			 * @param {object} e Touch 对象包含的属性
			 */
			touchStart (e) {
				this.startY = e.changedTouches[0].pageY
				this.startScrollTop = this.scrollTop				
				this.allowTouchMove = true //控制是否允许touchMove事件
			},
			
			/**
			 * 接触点改变,滑动时
			 * @param {object} e Touch 对象包含的属性
			 */
			touchMove (e) {
				//控制是否允许touchMove事件
				if(!this.allowTouchMove) {
					return
				}
				
				//解决因ios环境下scrollview的scrolltop可下拉为负数带来的体验问题
				this.$nextTick(function() {
					if(this.scrollTop<0) {
						this.allow_scroll_y = false
					} else {
						this.allow_scroll_y = true
					}
				});
				
				if(this.scrollTop <= 0) {
					if (e.changedTouches[0].pageY > this.startY) {
						// 下拉
						this.isDropDown = true
						if (!this.isRefreshing) {
						  // 获取拉取的间隔差  当前移动的y点          初始的y点        初始顶部距离
						  let diff = e.changedTouches[0].pageY - this.startY -  this.startScrollTop
						  this.top = Math.pow(diff, 0.8) + (this.dropDownState === 3 ? this.defaultOffset : 0);
						  if (this.top >= this.defaultOffset) {
							this.dropDownState = 2
							e.preventDefault();
						  } else { 
							this.dropDownState = 1
							// 去掉会导致ios无法刷新
							e.preventDefault();
						  }
						}
					} else {
						this.isDropDown = false
						this.dropDownState = 1
					}
				}
			},
			
			/**
			 * 触摸结束,手指离开屏幕时
			 * @param {object} e Touch 对象包含的属性
			 */
			touchEnd (e) {
			  //解决因ios环境下scrollview的scrolltop可下拉为负数带来的体验问题	
			  this.$nextTick(function() {
				  this.allow_scroll_y = true
			  });
			  
			  if (this.isDropDown && !this.isRefreshing) {
				if (this.top >= this.defaultOffset) {
				  // do refresh
				  this.isRefreshing = true
				  this.refresh();
				} else {
				  // cancel refresh
				  this.isRefreshing = false
				  this.isDropDown = false
				  this.dropDownState = 1
				  this.top = 0
				}
			  }
			},
			
			/**
			 * 刷新
			 */
			refresh () {
			  this.dropDownState = 3
			  this.top = this.defaultOffset
			  // 延时1200毫秒结束正在刷新动画
			  this.$emit('onRefresh');
			  setTimeout(() => {
				this.refreshDone();
			  }, 1200)			  
			},
			
			/**
			 * 刷新完成
			 */
			refreshDone () {
			  this.isRefreshing = false
			  this.isDropDown = false
			  this.dropDownState = 1
			  this.top = 0
			}
		}
	}
</script>

<style lang="scss" scoped>
	$height: 100rpx;
	.refresh-moudle {
		width: 100%;
		margin-top: -$height;
		-webkit-overflow-scrolling: touch; /* ios5+ */
		.pull-refresh {
			width: 100%;
			color: #999;
			transition-duration: 200ms;
			font-size: 28upx;
			.down-tip,
			.up-tip,
			.refresh-tip {
				display: flex;
				align-items: center;
				justify-content: center;
				height: $height;
			}
			.down-img,
			.up-img,
			.refresh-img{
				width: 50upx;
				height: 50upx;
				margin-right: 30upx;
			}
			.down-img {
			  transform: rotate(0deg);
			  animation: anticlockwise 0.8s ease;
			}
			@keyframes anticlockwise {
			  0% {
				transform: rotate(-180deg);
			  }
			  100% {
				transform: rotate(0deg);
			  }
			}
			.up-img {
			  transform: rotate(180deg);
			  animation: clockwise 0.8s ease;
			}
			@keyframes clockwise {
			  0% {
				transform: rotate(0deg);
			  }
			  100% {
				transform: rotate(-180deg);
			  }
			}
			.refresh-img {
			  animation: rotating 1.5s linear infinite;
			}
			@keyframes rotating {
			  0% {
				transform: rotate(0deg);
			  }
			  100% {
				transform: rotate(1turn);
			  }
			}
		}
	}
</style>

图标 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要修改 `scroll-view` 下刷新的样式,需要在 `scroll-view` 中添加下刷新组件,并设置其相应的样式。 以下是一个示例代码: ```html <scroll-view class="scrollview" scroll-y bindscrolltolower="scrolltolower" bindscrolltoupper="scrolltoupper"> <view class="refresh-view" style="height:{{refreshHeight}}px;"> <image class="refresh-image" src="../../static/img/refresh.png"></image> <view class="refresh-text">{{refreshText}}</view> </view> <!-- 此处为scroll-view的内容 --> </scroll-view> ``` 其中,`refresh-view` 为下刷新的容器,`refresh-image` 为下刷新的图标,`refresh-text` 为下刷新的文字。 接着,在 js 文件中设置下刷新的相关逻辑和样式: ```javascript Page({ data: { refreshHeight: 0, refreshText: '下刷新', refreshAnimation: {} }, // touchstart事件,记录下刷新的初始位置 touchstart: function (e) { this.setData({ startY: e.changedTouches[0].clientY }) }, // touchmove事件,计算下刷新的距离并更新样式 touchmove: function (e) { var moveY = e.changedTouches[0].clientY var disY = moveY - this.data.startY if (disY < 0) { return } var scrollHeight = this.data.scrollHeight var refreshHeight = this.data.refreshHeight var progress = disY / (refreshHeight + 10) * 100 if (progress > 100) { progress = 100 } var refreshText = '' if (progress < 20) { refreshText = '下刷新' } else if (progress < 80) { refreshText = '释放立即刷新' } else { refreshText = '正在刷新...' } this.setData({ refreshHeight: disY, progress: progress, refreshText: refreshText }) }, // touchend事件,触发下刷新并更新样式 touchend: function (e) { var refreshHeight = this.data.refreshHeight var scrollHeight = this.data.scrollHeight var progress = this.data.progress if (progress < 80) { this.setData({ refreshHeight: 0, refreshText: '下刷新' }) } else { this.setData({ refreshHeight: 50, refreshText: '正在刷新...' }) // 触发下刷新 this.refreshData() } }, // scrolltolower事件,触发上加载更多 scrolltolower: function () { // 触发上加载更多 this.loadMoreData() }, // scrolltoupper事件,触发下刷新 scrolltoupper: function () { this.setData({ refreshHeight: 50, refreshText: '正在刷新...' }) // 触发下刷新 this.refreshData() }, // 下刷新的逻辑 refreshData: function () { // 下刷新的具体实现 }, // 上加载更多的逻辑 loadMoreData: function () { // 上加载更多的具体实现 } }) ``` 在 css 文件中设置相应的样式: ```css .scrollview { height: 100%; overflow: auto; } .refresh-view { display: flex; justify-content: center; align-items: center; height: 0; transition: height 0.3s; } .refresh-image { width: 20px; height: 20px; margin-right: 10px; } .refresh-text { font-size: 14px; color: #666; } ``` 这样就可以实现自定义 `scroll-view` 下刷新的样式了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XJF_XH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值