mirror of
https://github.com/youzan/vant.git
synced 2025-10-15 23:55:08 +00:00
fix(SwipeCell): unintended stopPropagation when canceling a swipe (#13350)
This commit is contained in:
@@ -190,8 +190,8 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getClickHandler =
|
const getClickHandler =
|
||||||
(position: SwipeCellPosition, stop?: boolean) => (event: MouseEvent) => {
|
(position: SwipeCellPosition) => (event: MouseEvent) => {
|
||||||
if (stop) {
|
if (lockClick || opened) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,11 +209,7 @@ export default defineComponent({
|
|||||||
const contentSlot = slots[side];
|
const contentSlot = slots[side];
|
||||||
if (contentSlot) {
|
if (contentSlot) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div ref={ref} class={bem(side)} onClick={getClickHandler(side)}>
|
||||||
ref={ref}
|
|
||||||
class={bem(side)}
|
|
||||||
onClick={getClickHandler(side, true)}
|
|
||||||
>
|
|
||||||
{contentSlot()}
|
{contentSlot()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -244,7 +240,7 @@ export default defineComponent({
|
|||||||
<div
|
<div
|
||||||
ref={root}
|
ref={root}
|
||||||
class={bem()}
|
class={bem()}
|
||||||
onClick={getClickHandler('cell', lockClick)}
|
onClick={getClickHandler('cell')}
|
||||||
onTouchstartPassive={onTouchStart}
|
onTouchstartPassive={onTouchStart}
|
||||||
onTouchend={onTouchEnd}
|
onTouchend={onTouchEnd}
|
||||||
onTouchcancel={onTouchEnd}
|
onTouchcancel={onTouchEnd}
|
||||||
|
@@ -223,3 +223,69 @@ test('should not trigger close event again if already closed', () => {
|
|||||||
wrapper.vm.close();
|
wrapper.vm.close();
|
||||||
expect(wrapper.emitted('close')).toHaveLength(1);
|
expect(wrapper.emitted('close')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const createWithNativeWrapper = () => {
|
||||||
|
const onWrapperClick = vi.fn();
|
||||||
|
|
||||||
|
const component = {
|
||||||
|
template: `
|
||||||
|
<div class="native-wrapper" @click="onWrapperClick">
|
||||||
|
<swipe-cell v-bind="props" />
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
components: {
|
||||||
|
SwipeCell,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
props: defaultProps.props,
|
||||||
|
onWrapperClick,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = mount(component);
|
||||||
|
|
||||||
|
const track = wrapper.find('.van-swipe-cell__wrapper').element;
|
||||||
|
|
||||||
|
const triggerNativeClick = () => {
|
||||||
|
const clickEvent = new MouseEvent('click', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
});
|
||||||
|
track.dispatchEvent(clickEvent);
|
||||||
|
};
|
||||||
|
|
||||||
|
const swipeCell = wrapper.findComponent(SwipeCell);
|
||||||
|
|
||||||
|
return {
|
||||||
|
wrapper,
|
||||||
|
swipeCell,
|
||||||
|
onWrapperClick,
|
||||||
|
triggerNativeClick,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test('should not stop propagation of native click event when canceling swipe', async () => {
|
||||||
|
const { onWrapperClick, triggerNativeClick, swipeCell } =
|
||||||
|
createWithNativeWrapper();
|
||||||
|
|
||||||
|
triggerDrag(swipeCell, 5, 0);
|
||||||
|
|
||||||
|
await later();
|
||||||
|
|
||||||
|
triggerNativeClick();
|
||||||
|
expect(onWrapperClick).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not trigger native click event after drag operations in desktop simulation scenarios', async () => {
|
||||||
|
const { onWrapperClick, swipeCell } = createWithNativeWrapper();
|
||||||
|
|
||||||
|
triggerDrag(swipeCell, 50, 0);
|
||||||
|
await later();
|
||||||
|
expect(onWrapperClick).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
triggerDrag(swipeCell, -50, 0);
|
||||||
|
await later();
|
||||||
|
expect(onWrapperClick).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
@@ -51,6 +51,10 @@ export function trigger(
|
|||||||
return nextTick();
|
return nextTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TriggerDragOptions {
|
||||||
|
simulateDesktop?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
// simulate drag gesture
|
// simulate drag gesture
|
||||||
export function triggerDrag(
|
export function triggerDrag(
|
||||||
el:
|
el:
|
||||||
@@ -59,6 +63,9 @@ export function triggerDrag(
|
|||||||
| HTMLElement,
|
| HTMLElement,
|
||||||
relativeX = 0,
|
relativeX = 0,
|
||||||
relativeY = 0,
|
relativeY = 0,
|
||||||
|
options: TriggerDragOptions = {
|
||||||
|
simulateDesktop: true,
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
let x = relativeX;
|
let x = relativeX;
|
||||||
let y = relativeY;
|
let y = relativeY;
|
||||||
@@ -79,5 +86,9 @@ export function triggerDrag(
|
|||||||
trigger(el, 'touchmove', x, y);
|
trigger(el, 'touchmove', x, y);
|
||||||
trigger(el, 'touchend', x, y);
|
trigger(el, 'touchend', x, y);
|
||||||
|
|
||||||
|
if (options.simulateDesktop) {
|
||||||
|
trigger(el, 'click', x, y);
|
||||||
|
}
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user