|
|
@@ -1,242 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="nut-vert-scroll" ref="wrapper">
|
|
|
- <div class="nut-vert-list" ref="list" :style="{ 'min-height': listMinHeightStyle }">
|
|
|
- <div class="nut-vert-pulldown" v-if="isFirstPull">
|
|
|
- <div class="nut-vert-pulldown-txt" v-if="!isLoading">{{ pulldownTxt }}</div>
|
|
|
- <div class="nut-vert-pulldown-status" v-else>
|
|
|
- <span class="nut-vert-loading"></span>
|
|
|
- <span class="nut-vert-loading-txt">加载中...</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <slot name="list"></slot>
|
|
|
- <div class="nut-vert-loadmore">
|
|
|
- <template v-if="!isUnMore && isShowLoadMore">
|
|
|
- <!-- <div class="nut-vert-load-txt" >{{loadMoreTxt}}</div> -->
|
|
|
- <div class="nut-vert-load-status" v-if="isLoading">
|
|
|
- <span class="nut-vert-loading"></span>
|
|
|
- <span class="nut-vert-loading-txt">加载中...</span>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template v-else-if="isUnMore">
|
|
|
- <div class="nut-vert-unloadmore-txt">{{ unloadMoreTxt }}</div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-<script>
|
|
|
-export default {
|
|
|
- name: 'nut-vert-scroll',
|
|
|
- props: {
|
|
|
- stretch: {
|
|
|
- type: Number,
|
|
|
- default: 100,
|
|
|
- },
|
|
|
- isUnMore: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- isLoading: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- pulldownTxt: {
|
|
|
- type: String,
|
|
|
- default: '下拉刷新',
|
|
|
- },
|
|
|
- loadMoreTxt: {
|
|
|
- type: String,
|
|
|
- default: '上拉加载',
|
|
|
- },
|
|
|
- unloadMoreTxt: {
|
|
|
- type: String,
|
|
|
- default: '没有更多了',
|
|
|
- },
|
|
|
- threshold: {
|
|
|
- type: Number,
|
|
|
- default: 100,
|
|
|
- },
|
|
|
- propsTime: {
|
|
|
- type: Number,
|
|
|
- default: 0,
|
|
|
- },
|
|
|
- scrollTo: {
|
|
|
- type: Number,
|
|
|
- default: 1,
|
|
|
- },
|
|
|
- },
|
|
|
- watch: {
|
|
|
- isLoading: function (status) {
|
|
|
- if (!status && this.realMove === 0) {
|
|
|
- clearTimeout(this.timer);
|
|
|
- this.timer = setTimeout(() => {
|
|
|
- this.setTransform(this.realMove, 'end', null);
|
|
|
- }, this.propsTime);
|
|
|
- }
|
|
|
- },
|
|
|
- isUnMore: function () {
|
|
|
- this.isShow();
|
|
|
- },
|
|
|
- scrollTo: function (val) {
|
|
|
- if (typeof val === 'number' && !isNaN(val) && val <= 0) {
|
|
|
- this.setTransform(val, null, 500);
|
|
|
- this.$emit('scrollToCbk');
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- touchParams: {
|
|
|
- startY: 0,
|
|
|
- endY: 0,
|
|
|
- startTime: 0,
|
|
|
- endTime: 0,
|
|
|
- },
|
|
|
- translateY: 0,
|
|
|
- scrollDistance: 0,
|
|
|
- timer: null,
|
|
|
- timerEmit: null,
|
|
|
- realMove: 0,
|
|
|
- isShowLoadMore: false,
|
|
|
- listMinHeightStyle: 'auto',
|
|
|
- isFirstPull: true,
|
|
|
- };
|
|
|
- },
|
|
|
-
|
|
|
- methods: {
|
|
|
- isShow() {
|
|
|
- let wrapH = this.$refs.wrapper.offsetHeight;
|
|
|
- let listH = this.$refs.list.offsetHeight;
|
|
|
- if (wrapH < listH) {
|
|
|
- this.isShowLoadMore = true;
|
|
|
- this.listMinHeightStyle = 'auto';
|
|
|
- } else {
|
|
|
- this.isShowLoadMore = false;
|
|
|
- this.isFirstPull = true;
|
|
|
- this.listMinHeightStyle = `${wrapH}px`;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- setTransform(translateY = 0, type, time = 500) {
|
|
|
- if (type === 'end') {
|
|
|
- this.$refs.list.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)`;
|
|
|
- } else {
|
|
|
- this.$refs.list.style.webkitTransition = '';
|
|
|
- }
|
|
|
- this.$refs.list.style.webkitTransform = `translate3d(0, ${translateY}px, 0)`;
|
|
|
- this.scrollDistance = translateY;
|
|
|
- this.$emit('scrollChange', translateY);
|
|
|
- },
|
|
|
-
|
|
|
- setMove(move, type, time) {
|
|
|
- let updateMove = move + this.translateY;
|
|
|
- let h = this.$refs.wrapper.offsetHeight;
|
|
|
- let maxMove = -this.$refs.list.offsetHeight + h;
|
|
|
- if (type === 'end') {
|
|
|
- if (updateMove > 0) {
|
|
|
- this.realMove = 0;
|
|
|
- if ((!this.isShowLoadMore || this.isFirstPull) && !this.isLoading && updateMove > 20) {
|
|
|
- updateMove = 50;
|
|
|
- clearTimeout(this.timerEmit);
|
|
|
- this.timerEmit = setTimeout(() => {
|
|
|
- this.$emit('pulldown');
|
|
|
- }, time / 2);
|
|
|
- } else {
|
|
|
- this.isFirstPull = true;
|
|
|
- updateMove = 0;
|
|
|
- }
|
|
|
- } else if (updateMove < 0 && updateMove < maxMove + this.threshold) {
|
|
|
- if (updateMove < maxMove) {
|
|
|
- updateMove = maxMove;
|
|
|
- }
|
|
|
- this.realMove = maxMove;
|
|
|
- if (!this.isLoading && !this.isUnMore) {
|
|
|
- //clearTimeout(this.timerEmit);
|
|
|
- //this.timerEmit = setTimeout(() => {
|
|
|
- this.$emit('loadMore');
|
|
|
- // }, time / 2);
|
|
|
- }
|
|
|
- }
|
|
|
- // if (updateMove == 50 && !this.isLoading) {
|
|
|
- // clearTimeout(this.timer);
|
|
|
- // this.timer = setTimeout(() => {
|
|
|
- // this.setTransform(this.realMove, 'end', null);
|
|
|
- // }, 3000);
|
|
|
- // }
|
|
|
- this.setTransform(updateMove, type, time);
|
|
|
- } else {
|
|
|
- if (updateMove > 0 && updateMove > this.stretch) {
|
|
|
- updateMove = this.stretch;
|
|
|
- } else if (updateMove < maxMove - this.stretch) {
|
|
|
- updateMove = maxMove - this.stretch;
|
|
|
- }
|
|
|
- this.setTransform(updateMove, null, null);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- touchStart(event) {
|
|
|
- // event.preventDefault();
|
|
|
-
|
|
|
- let changedTouches = event.changedTouches[0];
|
|
|
- this.touchParams.startY = changedTouches.pageY;
|
|
|
- this.touchParams.startTime = event.timestamp || Date.now();
|
|
|
- this.translateY = this.scrollDistance;
|
|
|
- },
|
|
|
-
|
|
|
- touchMove(event) {
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- let changedTouches = event.changedTouches[0];
|
|
|
- this.touchParams.lastY = changedTouches.pageY;
|
|
|
- this.touchParams.lastTime = event.timestamp || Date.now();
|
|
|
- let move = this.touchParams.lastY - this.touchParams.startY;
|
|
|
- if (move < 0 && this.isShowLoadMore && this.isFirstPull) {
|
|
|
- this.isFirstPull = false;
|
|
|
- }
|
|
|
- this.setMove(move);
|
|
|
- },
|
|
|
-
|
|
|
- touchEnd(event) {
|
|
|
- // event.preventDefault();
|
|
|
-
|
|
|
- let changedTouches = event.changedTouches[0];
|
|
|
- this.touchParams.lastY = changedTouches.pageY;
|
|
|
- this.touchParams.lastTime = event.timestamp || Date.now();
|
|
|
- let move = this.touchParams.lastY - this.touchParams.startY;
|
|
|
-
|
|
|
- let moveTime = this.touchParams.lastTime - this.touchParams.startTime;
|
|
|
- let h = this.$refs.wrapper.offsetHeight;
|
|
|
- let maxMove = -this.$refs.list.offsetHeight + h;
|
|
|
-
|
|
|
- if (moveTime <= 300) {
|
|
|
- move = move * 2;
|
|
|
- if (move < 0 && move < maxMove) {
|
|
|
- move = maxMove;
|
|
|
- }
|
|
|
- moveTime = moveTime + 500;
|
|
|
- this.setMove(move, 'end', moveTime);
|
|
|
- } else {
|
|
|
- this.setMove(move, 'end');
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
-
|
|
|
- mounted() {
|
|
|
- this.$nextTick(() => {
|
|
|
- this.isShow();
|
|
|
- // 监听
|
|
|
- this.$el.addEventListener('touchstart', this.touchStart);
|
|
|
- this.$el.addEventListener('touchmove', this.touchMove);
|
|
|
- this.$el.addEventListener('touchend', this.touchEnd);
|
|
|
- });
|
|
|
- },
|
|
|
- beforeDestroy() {
|
|
|
- // 移除监听
|
|
|
- this.$el.removeEventListener('touchstart', this.touchStart);
|
|
|
- this.$el.removeEventListener('touchmove', this.touchMove);
|
|
|
- this.$el.removeEventListener('touchend', this.touchEnd);
|
|
|
- clearTimeout(this.timer);
|
|
|
- clearTimeout(this.timerEmit);
|
|
|
- },
|
|
|
-};
|
|
|
-</script>
|