[bugfix] Swipe: fix blank area when use width prop (#3751)

This commit is contained in:
neverland 2019-07-04 16:26:58 +08:00 committed by GitHub
parent 64bb96aeb0
commit 6d67f4572c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 34 deletions

View File

@ -83,7 +83,7 @@ export default {
### Set Swiper Item Size ### Set Swiper Item Size
```html ```html
<van-swipe :autoplay="3000" :width="300"> <van-swipe :loop="false" :width="300">
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item> <van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item> <van-swipe-item>3</van-swipe-item>

View File

@ -71,8 +71,10 @@ export default {
### 纵向滚动 ### 纵向滚动
设置`vertical`属性后滑块会纵向排列,此时需要指定滑块容器的高度
```html ```html
<van-swipe :autoplay="3000" vertical> <van-swipe style="height: 200px;" vertical>
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item> <van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item> <van-swipe-item>3</van-swipe-item>
@ -82,8 +84,10 @@ export default {
### 控制滑块大小 ### 控制滑块大小
滑块默认宽度为`100%`,可以通过`width`属性设置滑块的宽度,此属性不能与循环播放同时使用
```html ```html
<van-swipe :autoplay="3000" :width="300"> <van-swipe :loop="false" :width="300">
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item> <van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item> <van-swipe-item>3</van-swipe-item>
@ -93,6 +97,8 @@ export default {
### 自定义指示器 ### 自定义指示器
通过`indicator`插槽可以自定义指示器的样式
```html ```html
<van-swipe @change="onChange"> <van-swipe @change="onChange">
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
@ -135,8 +141,8 @@ export default {
| indicator-color | 指示器颜色 | `String` | `#1989fa` | - | | indicator-color | 指示器颜色 | `String` | `#1989fa` | - |
| vertical | 是否为纵向滚动 | `Boolean` | `false` | - | | vertical | 是否为纵向滚动 | `Boolean` | `false` | - |
| touchable | 是否可以通过手势滑动 | `Boolean` | `true` | - | | touchable | 是否可以通过手势滑动 | `Boolean` | `true` | - |
| width | 滑块宽度 | `Number` | `0` | - | | width | 滑块宽度 | `Number` | `auto` | - |
| height | 滑块高度 | `Number` | `0` | - | | height | 滑块高度 | `Number` | `auto` | - |
### Swipe Events ### Swipe Events

View File

@ -26,7 +26,7 @@
<demo-block :title="$t('title3')"> <demo-block :title="$t('title3')">
<van-swipe <van-swipe
indicator-color="white" indicator-color="white"
@change="onChange" @change="onChange1"
> >
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item> <van-swipe-item>2</van-swipe-item>
@ -40,6 +40,7 @@
vertical vertical
:autoplay="3000" :autoplay="3000"
indicator-color="white" indicator-color="white"
style="height: 200px;"
class="demo-swipe--vertical" class="demo-swipe--vertical"
> >
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
@ -51,7 +52,6 @@
<demo-block :title="$t('title5')"> <demo-block :title="$t('title5')">
<van-swipe <van-swipe
:autoplay="3000"
:width="300" :width="300"
:loop="false" :loop="false"
indicator-color="white" indicator-color="white"
@ -64,7 +64,7 @@
</demo-block> </demo-block>
<demo-block :title="$t('title6')"> <demo-block :title="$t('title6')">
<van-swipe @change="onChange"> <van-swipe @change="onChange2">
<van-swipe-item>1</van-swipe-item> <van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item> <van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item> <van-swipe-item>3</van-swipe-item>
@ -112,9 +112,12 @@ export default {
}, },
methods: { methods: {
onChange(index) { onChange1(index) {
this.current = index;
this.$toast(this.$t('message') + index); this.$toast(this.$t('message') + index);
},
onChange2(index) {
this.current = index;
} }
} }
}; };
@ -156,8 +159,6 @@ export default {
} }
&--vertical { &--vertical {
height: 200px;
.van-swipe-item { .van-swipe-item {
line-height: 200px; line-height: 200px;
} }

View File

@ -2,6 +2,7 @@ import { createNamespace } from '../utils';
import { preventDefault } from '../utils/dom/event'; import { preventDefault } from '../utils/dom/event';
import { TouchMixin } from '../mixins/touch'; import { TouchMixin } from '../mixins/touch';
import { BindEventMixin } from '../mixins/bind-event'; import { BindEventMixin } from '../mixins/bind-event';
import { range } from '../utils/format/number';
const [createComponent, bem] = createNamespace('swipe'); const [createComponent, bem] = createNamespace('swipe');
@ -116,6 +117,11 @@ export default createComponent({
return { return {
backgroundColor: this.indicatorColor 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 swipe position
initialize(active = this.initialSwipe) { initialize(active = this.initialSwipe) {
clearTimeout(this.timer); clearTimeout(this.timer);
if (this.$el) { if (this.$el) {
const rect = this.$el.getBoundingClientRect(); const rect = this.$el.getBoundingClientRect();
this.computedWidth = this.width || rect.width; this.computedWidth = this.width || rect.width;
this.computedHeight = this.height || rect.height; this.computedHeight = this.height || rect.height;
} }
this.swiping = true; this.swiping = true;
this.active = active; this.active = active;
this.offset = this.count > 1 ? -this.size * this.active : 0; this.offset = this.count > 1 ? -this.size * this.active : 0;
@ -157,7 +165,7 @@ export default createComponent({
if (this.isCorrectDirection) { if (this.isCorrectDirection) {
preventDefault(event, true); 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(); this.autoPlay();
}, },
move({ pace = 0, offset = 0, emitChange }) { getTargetActive(pace) {
const { delta, active, count, swipes, trackSize } = this; const { active, count } = this;
const atFirst = active === 0;
const atLast = active === count - 1;
const outOfBounds =
!this.loop &&
((atFirst && (offset > 0 || pace < 0)) || (atLast && (offset < 0 || pace > 0)));
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; return;
} }
if (swipes[0]) { const targetActive = this.getTargetActive(pace);
swipes[0].offset = atLast && (delta < 0 || pace > 0) ? trackSize : 0; const targetOffset = this.getTargetOffset(targetActive, offset);
}
if (swipes[count - 1]) { // auto move first and last swipe in loop mode
swipes[count - 1].offset = atFirst && (delta > 0 || pace < 0) ? -trackSize : 0; if (loop) {
} if (swipes[0]) {
const outRightBound = targetOffset < minOffset;
swipes[0].offset = outRightBound ? trackSize : 0;
}
if (pace && active + pace >= -1 && active + pace <= count) { if (swipes[count - 1]) {
this.active += pace; const outLeftBound = targetOffset > 0;
swipes[count - 1].offset = outLeftBound ? -trackSize : 0;
if (emitChange) {
this.$emit('change', this.activeIndicator);
} }
} }
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) { swipeTo(index) {
this.swiping = true; this.swiping = true;
this.resetTouchStatus(); this.resetTouchStatus();
this.correctPosition(); this.correctPosition();
setTimeout(() => { setTimeout(() => {
this.swiping = false; this.swiping = false;
this.move({ this.move({

View File

@ -36,7 +36,7 @@ exports[`renders demo correctly 1`] = `
</div> </div>
</div> </div>
<div> <div>
<div class="demo-swipe--vertical van-swipe"> <div class="demo-swipe--vertical van-swipe" style="height: 200px;">
<div class="van-swipe__track" style="height: 400px; transition-duration: 0ms; transform: translateY(0px);"> <div class="van-swipe__track" style="height: 400px; transition-duration: 0ms; transform: translateY(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">1</div> <div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">1</div>
<div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">2</div> <div class="van-swipe-item" style="width: 100px; height: 100px; transform: translateY(0px);">2</div>