UNPKG

@mypui/myp-ui

Version:

第一个高效且强悍的nvue开源组件库。做最好、最顺手的nvue组件库

282 lines (274 loc) 8.84 kB
// #ifndef APP-NVUE import {getTouchPoint} from '../../utils/element.js' // #endif export default { data() { return { // #ifdef APP-NVUE mypListId: 'head_swiper_list', // #endif // header mypAllHeight: uni.upx2px(248), // #ifndef APP-NVUE mypChildScrollable: false, mypParentScrollTop: 0, // scroll/refresh mypParentScrollable: true, mypDownHeight: 0, mypStartPoint: null, mypLastPoint: null, mypTheScrollHeight: 0, // scroll content height mypTheScrollTop: 0, // 记录滚动条的位置,并不是用来重置scrolltop mypStartTop: 0, // 记录开始时滚动条的位置 mypInTouchend: false, // 节流设置 mypFps: 40, // 1s内屏幕刷新的频数 mypMoveTime: 0, mypMoveTimeDiff: 0, mypScrollTopDeviation: 100, // scroll-view滚动到顶部时,此时的scroll-top不一定为0, 此值用于控制最大的误差 mypIsDownLoading: false, // 是否正在下拉刷新中 // down mypDown: { use: true, offset: uni.upx2px(140), inRate: 0.8, // 下拉的距离小于offset时,改变下拉区域高度比例;0-1,越小,越难拉 outRate: 0.2 // 下拉的距离大于offset时,改变下拉区域高度比例;0-1,越小,越难拉 }, mypIsMoveDown: false, mypDownMoveType: 0, mypIsDownReset: false // 下拉刷新,是否显示重置的过渡动画 // #endif } }, // #ifndef APP-NVUE computed: { mypMrScrollContentStyle() { let _style = 'position: relative;' _style += this.mypIsDownReset ? 'transition-property: transform; transition-duration: 300ms;' : '' _style += this.mypDownHeight > 0 ? `transform: translateY(${this.mypDownHeight}px);` : '' return _style }, mypMrRefreshStyle() { return 'position: absolute; transform: translateY(-100%); left:0;' }, mypCouldUnLash() { return this.mypDownHeight >= (this.mypDown.offset || 80) }, mypDownRate() { return this.mypDownHeight / (this.mypDown.offset || 80) } }, // #endif methods: { // #ifdef APP-NVUE mypSetScrollRef(ref) { ref && ref.setScrollRef(this.mypAllHeight) }, // #endif mypHandleRefresh(ref) { // #ifdef APP-NVUE const refresher = this.$refs['myp-refresher'] ref &&ref.toRefresh(refresher, (val) => { val && val.cancel() }, (val) => { val && val.cancel() }) // #endif // #ifndef APP-NVUE uni.$emit("swiperScrollRefresh") // #endif }, // #ifndef APP-NVUE // 手指开始触摸屏幕 mypTouchstartEvent(e) { this.mypStartPoint = getTouchPoint(e) this.mypStartTop = this.mypTheScrollTop || 0 this.mypLastPoint = this.mypStartPoint this.mypInTouchend = false }, // 手指在屏幕上滑动 // 注意:是手指位置的变化触发的。在scroll中,手指拖动scroll滚动,其实手指位置不变,scroll的滚动是不会触发touchmove的 mypTouchmoveEvent(e) { if (!this.mypDown.use) return; if (!this.mypStartPoint) return; // 限制/节流,可以使用时间,也可以使用高度 // 小于节流时间,则不处理 const t = new Date().getTime(); if (this.mypMoveTime && t - this.mypMoveTime < this.mypMoveTimeDiff) { return; } else { this.mypMoveTime = t this.mypMoveTimeDiff = 1000 / this.mypFps } const scrollTop = this.mypTheScrollTop const currentPoint = getTouchPoint(e) const moveY = currentPoint.y - this.mypStartPoint.y // (向下拉&&在顶部) scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove // scroll-view滚动到顶部时,scrollTop不一定为0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等 if (moveY > 0 && (scrollTop <= 0 || (scrollTop <= this.mypScrollTopDeviation && scrollTop === this.mypStartTop))) { // 是否可以下拉 if (!this.mypInTouchend && !this.mypIsDownLoading && !this.mypIsUpLoading) { let diff = currentPoint.y - this.mypLastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上) // 下拉距离 < 指定距离 if (this.mypDownHeight < this.mypDown.offset) { if (this.mypDownMoveType !== 1) { this.mypDownMoveType = 1; // 加入标记,保证只执行一次 this.mypDownInOffset() // 进入指定距离范围内那一刻的回调,只执行一次 this.mypIsMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来 } this.mypDownHeight += diff * this.mypDown.inRate; // 越往下,高度变化越小 // 下拉距离 >= 指定距离 } else { if (this.mypDownMoveType !== 2) { this.mypDownMoveType = 2; // 加入标记,保证只执行一次 this.mypDownOutOffset(); // 下拉超过指定距离那一刻的回调,只执行一次 this.mypIsMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来 } if (diff > 0) { // 向下拉 this.mypDownHeight += Math.round(diff * this.mypDown.outRate); // 越往下,高度变化越小 } else { // 向上收 this.mypDownHeight += diff; // 向上收回高度,则向上滑多少收多少高度 } } const rate = this.mypDownHeight / this.mypDown.offset; // 下拉区域当前高度与指定距离的比值 this.mypOnDownMoving(rate, this.mypDownHeight) // 下拉过程中的回调,一直在执行 } } this.mypLastPoint = currentPoint }, // 手指移开屏幕 mypTouchendEvent(e) { // 如果下拉区域高度已改变,则需重置回来 if (this.mypIsMoveDown) { if (this.mypDownHeight >= this.mypDown.offset) { // 符合触发刷新的条件 this.mypTriggerDownScroll() } else { // 不符合的话 则重置 this.mypDownHeight = 0; this.mypEndDownScroll() } this.mypDownMoveType = 0; this.mypIsMoveDown = false; } }, // scrollview滚动事件 mypScroll(e) { this.mypTheScrollTop = e.detail.scrollTop this.mypTheScrollHeight = e.detail.scrollHeight this.mypHandleParentScroll(e) }, mypHandleParentScroll(e) { const scrollTop = e.detail.scrollTop // 缓冲8px if (scrollTop >= this.mypAllHeight - 8) { // #ifdef H5 if (!this.mypParentScrollable) return; if (this.mypParentScrollTop === this.mypAllHeight) { this.mypParentScrollTop = this.mypAllHeight + 0.1 } else { this.mypParentScrollTop = this.mypAllHeight } setTimeout(()=>{ this.mypParentScrollable = false this.mypChildScrollable = true }, 0) return // #endif this.mypParentScrollable = false if (this.mypParentScrollTop === this.mypAllHeight) { this.mypParentScrollTop = this.mypAllHeight + 0.1 } else { this.mypParentScrollTop = this.mypAllHeight } this.mypChildScrollable = true } else { this.mypParentScrollable = true this.mypChildScrollable = false } }, // 进入下拉区域的那一刻 mypDownInOffset() { this.mypParentScrollable = false this.mypIsDownReset = false this.mypIsDownLoading = false }, // 超出下拉区域的那一刻 mypDownOutOffset() { this.mypParentScrollable = false this.mypIsDownReset = false this.mypIsDownLoading = false }, // 正在下拉的回调 mypOnDownMoving(rate, downHeight) { }, // 刷新 mypTriggerDownScroll() { this.mypParentScrollable = true this.mypIsDownReset = true this.mypIsDownLoading = true this.mypDownHeight = this.mypDown.offset this.mypHandleRefresh() }, mypEndDownScroll() { this.mypParentScrollable = true this.mypIsDownReset = true this.mypIsDownLoading = false this.mypDownHeight = 0 }, mypEndSuccess() { if (this.mypIsDownLoading) { this.mypEndDownScroll() } }, // 下拉刷新/上提加载,失败之后使用 mypEndError() { if (this.mypIsDownLoading) { this.mypEndDownScroll() } }, // for child-back event mypChildTouchMove(downHeight) { // console.log("move", downHeight) let dh = downHeight if (downHeight >= this.mypAllHeight) { dh = this.mypAllHeight } if (downHeight <= 0) { dh = 0 } // console.log(this.Scrollable, this.childScrollable) dh = this.mypAllHeight - dh // 限制10px移动距离,否则不动 // 一次性全部打开 if (downHeight > 10) { this.mypParentScrollable = true this.mypChildScrollable = false setTimeout(()=>{ this.mypParentScrollTop = 0 }, 0) } }, mypChildTouchEnd(downHeight) { // console.log("end", downHeight) } // #endif }, onLoad() { // #ifndef APP-NVUE const that = this uni.$on("swiperScrollRefreshSuc", ()=>{ that.mypEndSuccess() }) uni.$on("swiperScrollRefreshErr", ()=>{ that.mypEndError() }) // #endif }, onUnload() { // #ifndef APP-NVUE uni.$off("swiperScrollRefreshSuc") uni.$off("swiperScrollRefreshErr") // #endif } }