From 6d67f4572c72dc0432b1205994a74e0a769abefc Mon Sep 17 00:00:00 2001 From: neverland Date: Thu, 4 Jul 2019 16:26:58 +0800 Subject: [PATCH] [bugfix] Swipe: fix blank area when use width prop (#3751) --- src/swipe/README.md | 2 +- src/swipe/README.zh-CN.md | 14 +++- src/swipe/demo/index.vue | 15 ++-- src/swipe/index.js | 79 ++++++++++++++----- .../test/__snapshots__/demo.spec.js.snap | 2 +- 5 files changed, 78 insertions(+), 34 deletions(-) diff --git a/src/swipe/README.md b/src/swipe/README.md index 2b6dd84d5..3596ae042 100644 --- a/src/swipe/README.md +++ b/src/swipe/README.md @@ -83,7 +83,7 @@ export default { ### Set Swiper Item Size ```html - + 1 2 3 diff --git a/src/swipe/README.zh-CN.md b/src/swipe/README.zh-CN.md index f03eb16e2..18752cd08 100644 --- a/src/swipe/README.zh-CN.md +++ b/src/swipe/README.zh-CN.md @@ -71,8 +71,10 @@ export default { ### 纵向滚动 +设置`vertical`属性后滑块会纵向排列,此时需要指定滑块容器的高度 + ```html - + 1 2 3 @@ -82,8 +84,10 @@ export default { ### 控制滑块大小 +滑块默认宽度为`100%`,可以通过`width`属性设置滑块的宽度,此属性不能与循环播放同时使用 + ```html - + 1 2 3 @@ -93,6 +97,8 @@ export default { ### 自定义指示器 +通过`indicator`插槽可以自定义指示器的样式 + ```html 1 @@ -135,8 +141,8 @@ export default { | indicator-color | 指示器颜色 | `String` | `#1989fa` | - | | vertical | 是否为纵向滚动 | `Boolean` | `false` | - | | touchable | 是否可以通过手势滑动 | `Boolean` | `true` | - | -| width | 滑块宽度 | `Number` | `0` | - | -| height | 滑块高度 | `Number` | `0` | - | +| width | 滑块宽度 | `Number` | `auto` | - | +| height | 滑块高度 | `Number` | `auto` | - | ### Swipe Events diff --git a/src/swipe/demo/index.vue b/src/swipe/demo/index.vue index e6dc06b2b..c08db87f2 100644 --- a/src/swipe/demo/index.vue +++ b/src/swipe/demo/index.vue @@ -26,7 +26,7 @@ 1 2 @@ -40,6 +40,7 @@ vertical :autoplay="3000" indicator-color="white" + style="height: 200px;" class="demo-swipe--vertical" > 1 @@ -51,7 +52,6 @@ - + 1 2 3 @@ -112,9 +112,12 @@ export default { }, methods: { - onChange(index) { - this.current = index; + onChange1(index) { this.$toast(this.$t('message') + index); + }, + + onChange2(index) { + this.current = index; } } }; @@ -156,8 +159,6 @@ export default { } &--vertical { - height: 200px; - .van-swipe-item { line-height: 200px; } diff --git a/src/swipe/index.js b/src/swipe/index.js index 56ffe6b13..e8beee694 100644 --- a/src/swipe/index.js +++ b/src/swipe/index.js @@ -2,6 +2,7 @@ import { createNamespace } from '../utils'; import { preventDefault } from '../utils/dom/event'; import { TouchMixin } from '../mixins/touch'; import { BindEventMixin } from '../mixins/bind-event'; +import { range } from '../utils/format/number'; const [createComponent, bem] = createNamespace('swipe'); @@ -116,6 +117,11 @@ export default createComponent({ return { backgroundColor: this.indicatorColor }; + }, + + minOffset() { + const rect = this.$el.getBoundingClientRect(); + return (this.vertical ? rect.height : rect.width) - this.size * this.count; } }, @@ -123,11 +129,13 @@ export default createComponent({ // initialize swipe position initialize(active = this.initialSwipe) { clearTimeout(this.timer); + if (this.$el) { const rect = this.$el.getBoundingClientRect(); this.computedWidth = this.width || rect.width; this.computedHeight = this.height || rect.height; } + this.swiping = true; this.active = active; this.offset = this.count > 1 ? -this.size * this.active : 0; @@ -157,7 +165,7 @@ export default createComponent({ if (this.isCorrectDirection) { preventDefault(event, true); - this.move({ offset: Math.min(Math.max(this.delta, -this.size), this.size) }); + this.move({ offset: this.delta }); } }, @@ -176,41 +184,70 @@ export default createComponent({ this.autoPlay(); }, - move({ pace = 0, offset = 0, emitChange }) { - const { delta, active, count, swipes, trackSize } = this; - const atFirst = active === 0; - const atLast = active === count - 1; - const outOfBounds = - !this.loop && - ((atFirst && (offset > 0 || pace < 0)) || (atLast && (offset < 0 || pace > 0))); + getTargetActive(pace) { + const { active, count } = this; - if (outOfBounds || count <= 1) { + if (pace) { + if (this.loop) { + return range(active + pace, -1, count); + } + + return range(active + pace, 0, count - 1); + } + + return active; + }, + + getTargetOffset(targetActive, offset) { + let currentPosition = targetActive * this.size; + if (!this.loop) { + currentPosition = Math.min(currentPosition, -this.minOffset); + } + + let targetOffset = Math.round(offset - currentPosition); + if (!this.loop) { + targetOffset = range(targetOffset, this.minOffset, 0); + } + + return targetOffset; + }, + + move({ pace = 0, offset = 0, emitChange }) { + const { loop, count, active, swipes, trackSize, minOffset } = this; + + if (count <= 1) { return; } - if (swipes[0]) { - swipes[0].offset = atLast && (delta < 0 || pace > 0) ? trackSize : 0; - } + const targetActive = this.getTargetActive(pace); + const targetOffset = this.getTargetOffset(targetActive, offset); - if (swipes[count - 1]) { - swipes[count - 1].offset = atFirst && (delta > 0 || pace < 0) ? -trackSize : 0; - } + // auto move first and last swipe in loop mode + if (loop) { + if (swipes[0]) { + const outRightBound = targetOffset < minOffset; + swipes[0].offset = outRightBound ? trackSize : 0; + } - if (pace && active + pace >= -1 && active + pace <= count) { - this.active += pace; - - if (emitChange) { - this.$emit('change', this.activeIndicator); + if (swipes[count - 1]) { + const outLeftBound = targetOffset > 0; + swipes[count - 1].offset = outLeftBound ? -trackSize : 0; } } - this.offset = Math.round(offset - this.active * this.size); + this.active = targetActive; + this.offset = targetOffset; + + if (emitChange && targetActive !== active) { + this.$emit('change', this.activeIndicator); + } }, swipeTo(index) { this.swiping = true; this.resetTouchStatus(); this.correctPosition(); + setTimeout(() => { this.swiping = false; this.move({ diff --git a/src/swipe/test/__snapshots__/demo.spec.js.snap b/src/swipe/test/__snapshots__/demo.spec.js.snap index 92aa87521..72a46aabd 100644 --- a/src/swipe/test/__snapshots__/demo.spec.js.snap +++ b/src/swipe/test/__snapshots__/demo.spec.js.snap @@ -36,7 +36,7 @@ exports[`renders demo correctly 1`] = `
-
+
1
2