mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-22 22:49:15 +08:00
[new feature] Swipe: add immediate option of swipeTo method (#3821)
This commit is contained in:
parent
734c3259d8
commit
3c9dc4edfe
@ -1,5 +1,5 @@
|
|||||||
import { createNamespace, isDef } from '../utils';
|
import { createNamespace, isDef } from '../utils';
|
||||||
import { raf } from '../utils/dom/raf';
|
import { raf, doubleRaf } from '../utils/dom/raf';
|
||||||
import Cell from '../cell';
|
import Cell from '../cell';
|
||||||
import { cellProps } from '../cell/shared';
|
import { cellProps } from '../cell/shared';
|
||||||
import { ChildrenMixin } from '../mixins/relation';
|
import { ChildrenMixin } from '../mixins/relation';
|
||||||
@ -76,10 +76,8 @@ export default createComponent({
|
|||||||
wrapper.style.height = expanded ? 0 : contentHeight;
|
wrapper.style.height = expanded ? 0 : contentHeight;
|
||||||
|
|
||||||
// use double raf to ensure animation can start in mobile safari
|
// use double raf to ensure animation can start in mobile safari
|
||||||
raf(() => {
|
doubleRaf(() => {
|
||||||
raf(() => {
|
wrapper.style.height = expanded ? contentHeight : 0;
|
||||||
wrapper.style.height = expanded ? contentHeight : 0;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.onTransitionEnd();
|
this.onTransitionEnd();
|
||||||
|
@ -156,7 +156,13 @@ Use ref to get swipe instance and call instance methods
|
|||||||
|
|
||||||
| Name | Attribute | Return value | Description |
|
| 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
|
### Swipe Slots
|
||||||
|
|
||||||
|
@ -162,7 +162,13 @@ export default {
|
|||||||
|
|
||||||
| 方法名 | 参数 | 返回值 | 介绍 |
|
| 方法名 | 参数 | 返回值 | 介绍 |
|
||||||
|------|------|------|------|
|
|------|------|------|------|
|
||||||
| swipeTo | index: 目标位置的索引 | void | 滚动到目标位置 |
|
| swipeTo | index: 目标位置的索引, options: 选项 | void | 滚动到目标位置 |
|
||||||
|
|
||||||
|
### swipeTo Options 格式
|
||||||
|
|
||||||
|
| 名称 | 说明 | 类型 |
|
||||||
|
|------|------|------|
|
||||||
|
| immediate | 是否跳过动画 | `boolean` |
|
||||||
|
|
||||||
### Swipe Slots
|
### Swipe Slots
|
||||||
|
|
||||||
|
@ -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 { doubleRaf } from '../utils/dom/raf';
|
||||||
import { range } from '../utils/format/number';
|
import { range } from '../utils/format/number';
|
||||||
|
|
||||||
const [createComponent, bem] = createNamespace('swipe');
|
const [createComponent, bem] = createNamespace('swipe');
|
||||||
@ -108,6 +109,7 @@ export default createComponent({
|
|||||||
trackStyle() {
|
trackStyle() {
|
||||||
const mainAxis = this.vertical ? 'height' : 'width';
|
const mainAxis = this.vertical ? 'height' : 'width';
|
||||||
const crossAxis = this.vertical ? 'width' : 'height';
|
const crossAxis = this.vertical ? 'width' : 'height';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[mainAxis]: `${this.trackSize}px`,
|
[mainAxis]: `${this.trackSize}px`,
|
||||||
[crossAxis]: this[crossAxis] ? `${this[crossAxis]}px` : '',
|
[crossAxis]: this[crossAxis] ? `${this[crossAxis]}px` : '',
|
||||||
@ -246,24 +248,32 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
swipeTo(index) {
|
swipeTo(index, options = {}) {
|
||||||
this.swiping = true;
|
this.swiping = true;
|
||||||
this.resetTouchStatus();
|
this.resetTouchStatus();
|
||||||
this.correctPosition();
|
this.correctPosition();
|
||||||
|
|
||||||
setTimeout(() => {
|
doubleRaf(() => {
|
||||||
this.swiping = false;
|
|
||||||
this.move({
|
this.move({
|
||||||
pace: (index % this.count) - this.active,
|
pace: (index % this.count) - this.active,
|
||||||
emitChange: true
|
emitChange: true
|
||||||
});
|
});
|
||||||
}, 30);
|
|
||||||
|
if (options.immediate) {
|
||||||
|
doubleRaf(() => {
|
||||||
|
this.swiping = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.swiping = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
correctPosition() {
|
correctPosition() {
|
||||||
if (this.active <= -1) {
|
if (this.active <= -1) {
|
||||||
this.move({ pace: this.count });
|
this.move({ pace: this.count });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.active >= this.count) {
|
if (this.active >= this.count) {
|
||||||
this.move({ pace: -this.count });
|
this.move({ pace: -this.count });
|
||||||
}
|
}
|
||||||
@ -283,14 +293,14 @@ export default createComponent({
|
|||||||
this.resetTouchStatus();
|
this.resetTouchStatus();
|
||||||
this.correctPosition();
|
this.correctPosition();
|
||||||
|
|
||||||
setTimeout(() => {
|
doubleRaf(() => {
|
||||||
this.swiping = false;
|
this.swiping = false;
|
||||||
this.move({
|
this.move({
|
||||||
pace: 1,
|
pace: 1,
|
||||||
emitChange: true
|
emitChange: true
|
||||||
});
|
});
|
||||||
this.autoPlay();
|
this.autoPlay();
|
||||||
}, 30);
|
});
|
||||||
}, autoplay);
|
}, autoplay);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -48,7 +48,18 @@ test('swipeTo', async () => {
|
|||||||
const { swipe } = wrapper.vm.$refs;
|
const { swipe } = wrapper.vm.$refs;
|
||||||
swipe.swipeTo(2);
|
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);
|
expect(swipe.active).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,6 +28,13 @@ export function raf(fn: FrameRequestCallback): number {
|
|||||||
return iRaf.call(root, fn);
|
return iRaf.call(root, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// double raf for animation
|
||||||
|
export function doubleRaf(fn: FrameRequestCallback): void {
|
||||||
|
raf(() => {
|
||||||
|
raf(fn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function cancelRaf(id: number) {
|
export function cancelRaf(id: number) {
|
||||||
iCancel.call(root, id);
|
iCancel.call(root, id);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user