From 129a34e4288a7fcbe3fbf40106081078ff610eec Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Tue, 23 Feb 2021 11:28:12 +0800 Subject: [PATCH] 实现滚动无限加载之下拉刷新页面 --- plugins/infiniteScroll/CInfiniteScroll.vue | 149 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 148 insertions(+), 1 deletions(-) diff --git a/plugins/infiniteScroll/CInfiniteScroll.vue b/plugins/infiniteScroll/CInfiniteScroll.vue index f54c096..bea21ce 100644 --- a/plugins/infiniteScroll/CInfiniteScroll.vue +++ b/plugins/infiniteScroll/CInfiniteScroll.vue @@ -8,7 +8,31 @@ class="c-infinite-scroll" :scrollY="true" @scroll="evt=>onScroll(evt)" + @touchstart="evt=>onTouch(evt)" + @touchmove="evt=>onTouch(evt)" + @touchend="evt=>onTouch(evt)" > + <view + class="c-infinite-top" + :class="touching?'touching':''" + :style="{height: touch.driftTop+'rem'}" + > + <view class="inner"> + <view v-if="touch.dargState===2"> + <AtActivityIndicator /> + <text class="text">重新加载中...</text> + </view> + <view + class="tips" + v-else + :class="touch.dargState===0?'':'release'" + > + <view class="at-icon at-icon-arrow-down"></view> + <text class="text">下拉刷新</text> + <text class="text">释放刷新</text> + </view> + </view> + </view> <slot /> <view class="c-infinite-bottom"> <view @@ -39,21 +63,42 @@ AtActivityIndicator, }, props: { + // 是否自动初始化(自动加载第一页) autoInit: { type: Boolean, default: false, }, + // 加载页面回调 onLoadMore: Function, }, data() { return { + // 初始化状态 inital: false, + // 当前页面 current: 0, + // 总共页面 pageTotal: 1, + // 加载中状态 loading: false, + // 是否结束状态 ending: false, + // 上次滚动位置 lastScrollTop: 0, + // 滚动节流器 scrollTimer: 0, + // 是否已滚动 + scrolled: false, + // 滑屏数据 + touch: { + startX: 0, + startY: 0, + lastY: 0, + dargState: 0, + driftTop: 0, + }, + // 正在滑屏状态 + touching: false, }; }, methods: { @@ -73,7 +118,7 @@ current: this.current, next: this.current + 1, // 加载成功 - success: (options) => { + success: options => { setTimeout(() => { this.loading = false; // 没有数据 @@ -89,15 +134,31 @@ this.ending = true; } } + // 还原下拉 + if (this.touch.dargState === 2) { + this.touch.driftTop = 0; + setTimeout(() => { + this.touch.dargState = 0; + }, 300); + } }, 100); }, // 加载失败 fail: () => { this.loading = false; + // 还原下拉 + if (this.touch.dargState === 2) { + this.touch.driftTop = 0; + setTimeout(() => { + this.touch.dargState = 0; + }, 300); + } }, }); }, onScroll(evt) { + // 已经滚动(滚动后禁止下拉刷新) + this.scrolled = true; // 往上 if (this.lastScrollTop >= evt.detail.scrollTop) { this.lastScrollTop = evt.detail.scrollTop; @@ -116,6 +177,7 @@ } } }, + // 初始加载 initScroll() { // 已初始化,跳过 if (this.inital) { @@ -123,6 +185,91 @@ } this.hanldeLoadMore(); }, + // 手指拨动 + onTouch(evt) { + // 拉动长度(少于这个值的时候下拉但是不刷新) + const deviationY = 50; + // 拉动的最大高度 + const maxTransY = 100; + // 按下 + if (evt.type === 'touchstart') { + this.touching = true; + // 手指按下,重置是否已滚动 + this.scrolled = false; + if (evt.touches.length !== 1) { + return; + } + this.touch.startX = evt.touches[0].clientX; + this.touch.startY = evt.touches[0].clientY; + this.touch.lastY = evt.touches[0].clientY; + } + // 滑动 + else if (evt.type === 'touchmove') { + // 已滚动跳过 + if (this.scrolled) { + return; + } + // 加载中跳过 + if (this.loading) { + return; + } + this.touching = true; + // 左右偏移判断(向下拉时,如果左右偏移超过阀值不执行下拉操作) + const ratio = + Math.abs(evt.touches[0].clientX - this.touch.startX) / + Math.abs(evt.touches[0].clientY - this.touch.startY); + const dragDown = this.touch.lastY - evt.touches[0].clientY < 0; + this.touch.lastY = evt.touches[0].clientY; + if (dragDown && ratio > 0.3) { + return; + } + // 拖动距离 + const deltY = evt.touches[0].clientY - this.touch.startY; + // 拖动值=拖动距离/拖动倍率,使拖动的时候有粘滞的感觉 + const transY = Math.min(Math.abs(deltY) / 4, maxTransY); + if (deltY > 0) { + this.touch.driftTop = (transY / maxTransY) * 5; + // 超过阀值,可以刷新 + if (transY >= deviationY) { + this.touch.dargState = 1; + } + // 小于阀值,不能刷新 + else { + this.touch.dargState = 0; + } + } else { + this.touch.driftTop = 0; + } + } + // 松开 + else if (evt.type === 'touchend') { + this.touching = false; + // 已滚动跳过 + if (this.scrolled) { + this.touch.driftTop = 0; + return; + } + // 加载中跳过 + if (this.loading) { + this.touch.driftTop = 0; + return; + } + // 不刷新 + if (this.touch.dargState === 0) { + this.touch.driftTop = 0; + return; + } + // 刷新数据 + if (this.touch.dargState === 1) { + this.touch.driftTop = (deviationY / maxTransY) * 5; + // 重新加载 + this.touch.dargState = 2; + this.ending = false; + this.current = 0; + this.hanldeLoadMore(); + } + } + }, }, mounted() { // 开启自动初始化 -- Gitblit v1.9.1