[new feature] Swipe: add immediate option of swipeTo method (#3821)

This commit is contained in:
neverland 2019-07-11 16:09:20 +08:00 committed by GitHub
parent 734c3259d8
commit 3c9dc4edfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 14 deletions

View File

@ -1,5 +1,5 @@
import { createNamespace, isDef } from '../utils';
import { raf } from '../utils/dom/raf';
import { raf, doubleRaf } from '../utils/dom/raf';
import Cell from '../cell';
import { cellProps } from '../cell/shared';
import { ChildrenMixin } from '../mixins/relation';
@ -76,11 +76,9 @@ export default createComponent({
wrapper.style.height = expanded ? 0 : contentHeight;
// use double raf to ensure animation can start in mobile safari
raf(() => {
raf(() => {
doubleRaf(() => {
wrapper.style.height = expanded ? contentHeight : 0;
});
});
} else {
this.onTransitionEnd();
}

View File

@ -156,7 +156,13 @@ Use ref to get swipe instance and call instance methods
| Name | Attribute | Return value | Description |
|------|------|------|------|
| swipeTo | index: target index | void | Swipe to target index |
| swipeTo | index: target index, options: Options | void | Swipe to target index |
### swipeTo Options
| Name | Description | Type |
|------|------|------|
| immediate | Whether to skip animation | `boolean` |
### Swipe Slots

View File

@ -162,7 +162,13 @@ export default {
| 方法名 | 参数 | 返回值 | 介绍 |
|------|------|------|------|
| swipeTo | index: 目标位置的索引 | void | 滚动到目标位置 |
| swipeTo | index: 目标位置的索引, options: 选项 | void | 滚动到目标位置 |
### swipeTo Options 格式
| 名称 | 说明 | 类型 |
|------|------|------|
| immediate | 是否跳过动画 | `boolean` |
### Swipe Slots

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 { doubleRaf } from '../utils/dom/raf';
import { range } from '../utils/format/number';
const [createComponent, bem] = createNamespace('swipe');
@ -108,6 +109,7 @@ export default createComponent({
trackStyle() {
const mainAxis = this.vertical ? 'height' : 'width';
const crossAxis = this.vertical ? 'width' : 'height';
return {
[mainAxis]: `${this.trackSize}px`,
[crossAxis]: this[crossAxis] ? `${this[crossAxis]}px` : '',
@ -246,24 +248,32 @@ export default createComponent({
}
},
swipeTo(index) {
swipeTo(index, options = {}) {
this.swiping = true;
this.resetTouchStatus();
this.correctPosition();
setTimeout(() => {
this.swiping = false;
doubleRaf(() => {
this.move({
pace: (index % this.count) - this.active,
emitChange: true
});
}, 30);
if (options.immediate) {
doubleRaf(() => {
this.swiping = false;
});
} else {
this.swiping = false;
}
});
},
correctPosition() {
if (this.active <= -1) {
this.move({ pace: this.count });
}
if (this.active >= this.count) {
this.move({ pace: -this.count });
}
@ -283,14 +293,14 @@ export default createComponent({
this.resetTouchStatus();
this.correctPosition();
setTimeout(() => {
doubleRaf(() => {
this.swiping = false;
this.move({
pace: 1,
emitChange: true
});
this.autoPlay();
}, 30);
});
}, autoplay);
}
},

View File

@ -48,7 +48,18 @@ test('swipeTo', async () => {
const { swipe } = wrapper.vm.$refs;
swipe.swipeTo(2);
await later(30);
await later(50);
expect(swipe.active).toEqual(2);
});
test('swipeTo immediate', async () => {
const wrapper = mount(Component);
const { swipe } = wrapper.vm.$refs;
swipe.swipeTo(2, {
immediate: true
});
await later(100);
expect(swipe.active).toEqual(2);
});

View File

@ -28,6 +28,13 @@ export function raf(fn: FrameRequestCallback): number {
return iRaf.call(root, fn);
}
// double raf for animation
export function doubleRaf(fn: FrameRequestCallback): void {
raf(() => {
raf(fn);
});
}
export function cancelRaf(id: number) {
iCancel.call(root, id);
}