From a18f1ecf05842337f1eb39a6871adb8cb4024093 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 24 Jul 2024 23:25:22 +0800 Subject: [PATCH] fix(defineModel): correct update with multiple changes in same tick (#11430) close #11429 --- .../__tests__/helpers/useModel.spec.ts | 25 +++++++++++-------- packages/runtime-core/src/helpers/useModel.ts | 7 ++++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/runtime-core/__tests__/helpers/useModel.spec.ts b/packages/runtime-core/__tests__/helpers/useModel.spec.ts index 097e52f9167..4c30de2f26a 100644 --- a/packages/runtime-core/__tests__/helpers/useModel.spec.ts +++ b/packages/runtime-core/__tests__/helpers/useModel.spec.ts @@ -614,24 +614,23 @@ describe('useModel', () => { }) test('set no change value', async () => { - let changeChildMsg: (() => void) | null = null + let changeChildMsg!: (val: string) => void - const compRender = vi.fn() + const setValue = vi.fn() const Comp = defineComponent({ props: ['msg'], emits: ['update:msg'], setup(props) { const childMsg = useModel(props, 'msg') - changeChildMsg = () => { - childMsg.value = childMsg.value - } + changeChildMsg = (val: string) => (childMsg.value = val) return () => { return childMsg.value } }, }) - const msg = ref('HI') + const defaultVal = 'defaultVal' + const msg = ref(defaultVal) const Parent = defineComponent({ setup() { return () => @@ -639,7 +638,7 @@ describe('useModel', () => { msg: msg.value, 'onUpdate:msg': val => { msg.value = val - compRender() + setValue() }, }) }, @@ -648,8 +647,14 @@ describe('useModel', () => { const root = nodeOps.createElement('div') render(h(Parent), root) - expect(compRender).toBeCalledTimes(0) - changeChildMsg!() - expect(compRender).toBeCalledTimes(0) + expect(setValue).toBeCalledTimes(0) + + changeChildMsg(defaultVal) + expect(setValue).toBeCalledTimes(0) + + changeChildMsg('changed') + changeChildMsg(defaultVal) + expect(setValue).toBeCalledTimes(2) + expect(msg.value).toBe(defaultVal) }) }) diff --git a/packages/runtime-core/src/helpers/useModel.ts b/packages/runtime-core/src/helpers/useModel.ts index 493264ea73a..c490a699f84 100644 --- a/packages/runtime-core/src/helpers/useModel.ts +++ b/packages/runtime-core/src/helpers/useModel.ts @@ -33,7 +33,7 @@ export function useModel( const res = customRef((track, trigger) => { let localValue: any - let prevSetValue: any + let prevSetValue: any = EMPTY_OBJ let prevEmittedValue: any watchSyncEffect(() => { @@ -51,7 +51,10 @@ export function useModel( }, set(value) { - if (!hasChanged(value, localValue)) { + if ( + !hasChanged(value, localValue) && + !(prevSetValue !== EMPTY_OBJ && hasChanged(value, prevSetValue)) + ) { return } const rawProps = i.vnode!.props