[breaking change] reconstruct Swipe component (#194)
* Swipe: reconstruct * [bugfix]: Swipe autoplay [bugfix] AddressEdit doc link
This commit is contained in:
+126
-62
@@ -1,97 +1,161 @@
|
||||
<template>
|
||||
<div class="van-swipe">
|
||||
<div class="van-swipe__items">
|
||||
<div
|
||||
:style="trackStyle"
|
||||
class="van-swipe__track"
|
||||
@touchstart="onTouchStart"
|
||||
@touchmove="onTouchMove"
|
||||
@touchend="onTouchEnd"
|
||||
@touchcancel="onTouchEnd"
|
||||
@transitionend="$emit('change', activeIndicator)"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div
|
||||
class="van-swipe__indicators"
|
||||
v-if="showIndicators && swipes.length > 1"
|
||||
>
|
||||
<span class="van-swipe__indicator" v-for="(item, index) in swipes.length" :key="index" :class="{
|
||||
'van-swipe__indicator--active': currIndex === index
|
||||
}">
|
||||
</span>
|
||||
<div class="van-swipe__indicators" v-if="showIndicators && count > 1">
|
||||
<i v-for="index in count" :class="{ 'van-swipe__indicator--active': index - 1 === activeIndicator }" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Input from './input';
|
||||
import Scroll from './scroll';
|
||||
import SpringDummy from './spring_dummy';
|
||||
|
||||
export default {
|
||||
name: 'van-swipe',
|
||||
|
||||
props: {
|
||||
autoPlay: Boolean,
|
||||
autoplay: Number,
|
||||
showIndicators: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 500
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
currIndex: 0,
|
||||
swipes: []
|
||||
offset: 0,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
active: 0,
|
||||
deltaX: 0,
|
||||
swipes: [],
|
||||
childrenOffset: [],
|
||||
direction: '',
|
||||
currentDuration: 0,
|
||||
width: window.innerWidth
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.input = new Input(this.$el, {
|
||||
listenMoving: true
|
||||
});
|
||||
|
||||
this.input.on('move', function(dist, isEnd, e, extra) {
|
||||
if (extra.orgDirection) {
|
||||
e.preventDefault();
|
||||
scroll.movePage(dist.x, isEnd);
|
||||
}
|
||||
});
|
||||
|
||||
this.scroll = new Scroll(this.$el, {
|
||||
autoPlay: this.autoPlay
|
||||
});
|
||||
|
||||
const scroll = this.scroll;
|
||||
scroll.on('pageChangeEnd', this.onPageChangeEnd);
|
||||
|
||||
const dummy = new SpringDummy(scroll, this.input);
|
||||
|
||||
dummy.on('bounce', function(dist, isEnd) {
|
||||
scroll.movePage(dist.x, isEnd);
|
||||
}).on('autoPlay', function(dist, isEnd) {
|
||||
scroll.movePage(dist.x, isEnd);
|
||||
});
|
||||
this.dummy = dummy;
|
||||
this.move(0);
|
||||
this.autoPlay();
|
||||
},
|
||||
|
||||
watch: {
|
||||
swipes(value) {
|
||||
if (this.autoPlay && value.length > 1) {
|
||||
this.dummy.initMove();
|
||||
} else {
|
||||
this.dummy.clearMove();
|
||||
}
|
||||
this.scroll.update();
|
||||
return value;
|
||||
computed: {
|
||||
count() {
|
||||
return this.swipes.length;
|
||||
},
|
||||
|
||||
autoPlay(value) {
|
||||
if (value && this.swipes.length > 1) {
|
||||
this.dummy.initMove();
|
||||
} else {
|
||||
this.dummy.clearMove();
|
||||
}
|
||||
return value;
|
||||
trackStyle() {
|
||||
return this.count === 1 ? {} : {
|
||||
paddingLeft: this.width + 'px',
|
||||
width: (this.count + 2) * this.width + 'px',
|
||||
transitionDuration: `${this.currentDuration}ms`,
|
||||
transform: `translate3d(${this.offset}px, 0, 0)`
|
||||
};
|
||||
},
|
||||
|
||||
activeIndicator() {
|
||||
return (this.active + this.count) % this.count;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onPageChangeEnd(page, currIndex) {
|
||||
this.currIndex = +currIndex;
|
||||
this.$emit('pagechange:end', page, currIndex);
|
||||
onTouchStart(event) {
|
||||
clearTimeout(this.timer);
|
||||
|
||||
this.deltaX = 0;
|
||||
this.direction = '';
|
||||
this.currentDuration = 0;
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
|
||||
if (this.active === -1) {
|
||||
this.move(this.count);
|
||||
}
|
||||
if (this.active === this.count) {
|
||||
this.move(-this.count);
|
||||
}
|
||||
},
|
||||
|
||||
onTouchMove(event) {
|
||||
this.direction = this.direction || this.getDirection(event.touches[0]);
|
||||
|
||||
if (this.direction === 'horizontal') {
|
||||
event.preventDefault();
|
||||
this.deltaX = event.touches[0].clientX - this.startX;
|
||||
this.move(0, this.range(this.deltaX, [-this.width, this.width]));
|
||||
}
|
||||
},
|
||||
|
||||
onTouchEnd() {
|
||||
if (this.deltaX) {
|
||||
this.move(Math.abs(this.deltaX) > 50 ? (this.deltaX > 0 ? -1 : 1) : 0);
|
||||
this.currentDuration = this.duration;
|
||||
}
|
||||
this.autoPlay();
|
||||
},
|
||||
|
||||
move(move = 0, offset = 0) {
|
||||
const { active, count, swipes, deltaX, width } = this;
|
||||
|
||||
if (move) {
|
||||
if (active === -1) {
|
||||
swipes[count - 1].offset = 0;
|
||||
}
|
||||
swipes[0].offset = active === count - 1 ? count * width : 0;
|
||||
|
||||
this.active += move;
|
||||
} else {
|
||||
if (active === 0) {
|
||||
swipes[count - 1].offset = deltaX > 0 ? -count * width : 0;
|
||||
} else if (active === count - 1) {
|
||||
swipes[0].offset = deltaX < 0 ? count * width : 0;
|
||||
}
|
||||
}
|
||||
this.offset = offset - (this.active + 1) * this.width;
|
||||
},
|
||||
|
||||
autoPlay() {
|
||||
const { autoplay } = this;
|
||||
if (autoplay && this.count > 1) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.currentDuration = 0;
|
||||
|
||||
if (this.active === this.count) {
|
||||
this.move(-this.count);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.currentDuration = this.duration;
|
||||
this.move(1);
|
||||
this.autoPlay();
|
||||
}, 30);
|
||||
}, autoplay);
|
||||
}
|
||||
},
|
||||
|
||||
getDirection(touch) {
|
||||
const distanceX = Math.abs(touch.clientX - this.startX);
|
||||
const distanceY = Math.abs(touch.clientY - this.startY);
|
||||
return distanceX > distanceY ? 'horizontal' : distanceX < distanceY ? 'vertical' : '';
|
||||
},
|
||||
|
||||
range(num, arr) {
|
||||
return Math.min(Math.max(num, arr[0]), arr[1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user