[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
```html
<van-swipe :autoplay="3000" :width="300">
<van-swipe :loop="false" :width="300">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>

View File

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

View File

@ -26,7 +26,7 @@
<demo-block :title="$t('title3')">
<van-swipe
indicator-color="white"
@change="onChange"
@change="onChange1"
>
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
@ -40,6 +40,7 @@
vertical
:autoplay="3000"
indicator-color="white"
style="height: 200px;"
class="demo-swipe--vertical"
>
<van-swipe-item>1</van-swipe-item>
@ -51,7 +52,6 @@
<demo-block :title="$t('title5')">
<van-swipe
:autoplay="3000"
:width="300"
:loop="false"
indicator-color="white"
@ -64,7 +64,7 @@
</demo-block>
<demo-block :title="$t('title6')">
<van-swipe @change="onChange">
<van-swipe @change="onChange2">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
@ -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;
}

View File

@ -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;
}
const targetActive = this.getTargetActive(pace);
const targetOffset = this.getTargetOffset(targetActive, offset);
// auto move first and last swipe in loop mode
if (loop) {
if (swipes[0]) {
swipes[0].offset = atLast && (delta < 0 || pace > 0) ? trackSize : 0;
const outRightBound = targetOffset < minOffset;
swipes[0].offset = outRightBound ? trackSize : 0;
}
if (swipes[count - 1]) {
swipes[count - 1].offset = atFirst && (delta > 0 || pace < 0) ? -trackSize : 0;
const outLeftBound = targetOffset > 0;
swipes[count - 1].offset = outLeftBound ? -trackSize : 0;
}
}
if (pace && active + pace >= -1 && active + pace <= count) {
this.active += pace;
this.active = targetActive;
this.offset = targetOffset;
if (emitChange) {
if (emitChange && targetActive !== active) {
this.$emit('change', this.activeIndicator);
}
}
this.offset = Math.round(offset - this.active * this.size);
},
swipeTo(index) {
this.swiping = true;
this.resetTouchStatus();
this.correctPosition();
setTimeout(() => {
this.swiping = false;
this.move({

View File

@ -36,7 +36,7 @@ exports[`renders demo correctly 1`] = `
</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-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>