From 9d0eba916f3bf6fb5c03222400edae1a2db7444f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=B6=E8=BF=9C=E6=96=B9?= Date: Thu, 9 Nov 2023 14:32:08 +0800 Subject: [PATCH 01/42] fix(compiler-core): fix `resolveParserPlugins` decorators check (#9566) close #9560 --- packages/compiler-sfc/src/script/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-sfc/src/script/context.ts b/packages/compiler-sfc/src/script/context.ts index 692eab3ab9e..b05b8d910ee 100644 --- a/packages/compiler-sfc/src/script/context.ts +++ b/packages/compiler-sfc/src/script/context.ts @@ -164,7 +164,7 @@ export function resolveParserPlugins( } if (lang === 'ts' || lang === 'tsx') { plugins.push(['typescript', { dts }]) - if (!plugins.includes('decorators')) { + if (!userPlugins || !userPlugins.includes('decorators')) { plugins.push('decorators-legacy') } } From 94c049d930d922069e38ea8700d7ff0970f71e61 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Thu, 9 Nov 2023 06:52:28 +0000 Subject: [PATCH 02/42] fix(types): remove optional properties from defineProps return type (#6421) close #6420 --- packages/dts-test/setupHelpers.test-d.ts | 12 +++++++++++- packages/runtime-core/src/apiSetupHelpers.ts | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/dts-test/setupHelpers.test-d.ts b/packages/dts-test/setupHelpers.test-d.ts index feb4085dea0..838e376da2d 100644 --- a/packages/dts-test/setupHelpers.test-d.ts +++ b/packages/dts-test/setupHelpers.test-d.ts @@ -8,7 +8,8 @@ import { defineSlots, VNode, Ref, - defineModel + defineModel, + toRefs } from 'vue' import { describe, expectType } from './utils' import { defineComponent } from 'vue' @@ -20,6 +21,7 @@ describe('defineProps w/ type declaration', () => { foo: string bool?: boolean boolAndUndefined: boolean | undefined + file?: File | File[] }>() // explicitly declared type should be refined expectType(props.foo) @@ -328,3 +330,11 @@ describe('useSlots', () => { const slots = useSlots() expectType(slots) }) + +// #6420 +describe('toRefs w/ type declaration', () => { + const props = defineProps<{ + file?: File | File[] + }>() + expectType>(toRefs(props).file) +}) diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 93200667081..cff0c6511e2 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -4,7 +4,8 @@ import { isFunction, Prettify, UnionToIntersection, - extend + extend, + LooseRequired } from '@vue/shared' import { getCurrentInstance, @@ -82,7 +83,7 @@ export function defineProps< >(props: PP): Prettify>> // overload 3: typed-based declaration export function defineProps(): DefineProps< - TypeProps, + LooseRequired, BooleanKey > // implementation From 40f4b77bb570868cb6e47791078767797e465989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E9=9B=BE=E4=B8=89=E8=AF=AD?= <32354856+baiwusanyu-c@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:14:38 +0800 Subject: [PATCH 03/42] fix(v-model): avoid overwriting number input with same value (#7004) close #7003 --- .../__tests__/directives/vModel.spec.ts | 55 +++++++++++++++++++ packages/runtime-dom/src/directives/vModel.ts | 23 ++++---- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index 73b8f18afc0..acf1b40b696 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -101,6 +101,61 @@ describe('vModel', () => { expect(data.value).toEqual(1) }) + // #7003 + it('should work with number input and be able to update rendering correctly', async () => { + const setValue1 = function (this: any, value: any) { + this.value1 = value + } + const setValue2 = function (this: any, value: any) { + this.value2 = value + } + const component = defineComponent({ + data() { + return { value1: 1.002, value2: 1.002 } + }, + render() { + return [ + withVModel( + h('input', { + id: 'input_num1', + type: 'number', + 'onUpdate:modelValue': setValue1.bind(this) + }), + this.value1 + ), + withVModel( + h('input', { + id: 'input_num2', + type: 'number', + 'onUpdate:modelValue': setValue2.bind(this) + }), + this.value2 + ) + ] + } + }) + render(h(component), root) + const data = root._vnode.component.data + + const inputNum1 = root.querySelector('#input_num1')! + expect(inputNum1.value).toBe('1.002') + + const inputNum2 = root.querySelector('#input_num2')! + expect(inputNum2.value).toBe('1.002') + + inputNum1.value = '1.00' + triggerEvent('input', inputNum1) + await nextTick() + expect(data.value1).toBe(1) + + inputNum2.value = '1.00' + triggerEvent('input', inputNum2) + await nextTick() + expect(data.value2).toBe(1) + + expect(inputNum1.value).toBe('1.00') + }) + it('should work with multiple listeners', async () => { const spy = vi.fn() const component = defineComponent({ diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 89cd5f9d49f..1bc4e76dfbc 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -83,24 +83,25 @@ export const vModelText: ModelDirective< el[assignKey] = getModelAssigner(vnode) // avoid clearing unresolved text. #2302 if ((el as any).composing) return + + const elValue = + number || el.type === 'number' ? looseToNumber(el.value) : el.value + const newValue = value == null ? '' : value + + if (elValue === newValue) { + return + } + if (document.activeElement === el && el.type !== 'range') { if (lazy) { return } - if (trim && el.value.trim() === value) { - return - } - if ( - (number || el.type === 'number') && - looseToNumber(el.value) === value - ) { + if (trim && el.value.trim() === newValue) { return } } - const newValue = value == null ? '' : value - if (el.value !== newValue) { - el.value = newValue - } + + el.value = newValue } } From d11e978fc98dcc83526c167e603b8308f317f786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AB=E9=9B=A8=E6=B0=B4=E8=BF=87=E6=BB=A4=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E6=B0=94-Rain?= <958414905@qq.com> Date: Thu, 9 Nov 2023 17:15:56 +0800 Subject: [PATCH 04/42] fix(hmr/transition): fix kept-alive component inside transition disappearing after hmr (#7126) fix #7121 --- packages/runtime-core/__tests__/hmr.spec.ts | 69 +++++++++++++++++++ .../src/components/BaseTransition.ts | 6 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/hmr.spec.ts b/packages/runtime-core/__tests__/hmr.spec.ts index 2e989e368a3..a5ec90ad7d3 100644 --- a/packages/runtime-core/__tests__/hmr.spec.ts +++ b/packages/runtime-core/__tests__/hmr.spec.ts @@ -218,6 +218,75 @@ describe('hot module replacement', () => { expect(deactiveSpy).toHaveBeenCalledTimes(1) }) + // #7121 + test('reload KeepAlive slot in Transition', async () => { + const root = nodeOps.createElement('div') + const childId = 'test-transition-keep-alive-reload' + const unmountSpy = vi.fn() + const mountSpy = vi.fn() + const activeSpy = vi.fn() + const deactiveSpy = vi.fn() + + const Child: ComponentOptions = { + __hmrId: childId, + data() { + return { count: 0 } + }, + unmounted: unmountSpy, + render: compileToFunction(`
{{ count }}
`) + } + createRecord(childId, Child) + + const Parent: ComponentOptions = { + components: { Child }, + data() { + return { toggle: true } + }, + render: compileToFunction( + `` + ) + } + + render(h(Parent), root) + expect(serializeInner(root)).toBe(`
0
`) + + reload(childId, { + __hmrId: childId, + data() { + return { count: 1 } + }, + mounted: mountSpy, + unmounted: unmountSpy, + activated: activeSpy, + deactivated: deactiveSpy, + render: compileToFunction(`
{{ count }}
`) + }) + await nextTick() + expect(serializeInner(root)).toBe(`
1
`) + expect(unmountSpy).toHaveBeenCalledTimes(1) + expect(mountSpy).toHaveBeenCalledTimes(1) + expect(activeSpy).toHaveBeenCalledTimes(1) + expect(deactiveSpy).toHaveBeenCalledTimes(0) + + // should not unmount when toggling + triggerEvent(root.children[1] as TestElement, 'click') + await nextTick() + expect(serializeInner(root)).toBe(``) + expect(unmountSpy).toHaveBeenCalledTimes(1) + expect(mountSpy).toHaveBeenCalledTimes(1) + expect(activeSpy).toHaveBeenCalledTimes(1) + expect(deactiveSpy).toHaveBeenCalledTimes(1) + + // should not mount when toggling + triggerEvent(root.children[1] as TestElement, 'click') + await nextTick() + expect(serializeInner(root)).toBe(`
1
`) + expect(unmountSpy).toHaveBeenCalledTimes(1) + expect(mountSpy).toHaveBeenCalledTimes(1) + expect(activeSpy).toHaveBeenCalledTimes(2) + expect(deactiveSpy).toHaveBeenCalledTimes(1) + }) + test('reload class component', async () => { const root = nodeOps.createElement('div') const childId = 'test4-child' diff --git a/packages/runtime-core/src/components/BaseTransition.ts b/packages/runtime-core/src/components/BaseTransition.ts index 9cb80b94ef0..8711d7271c2 100644 --- a/packages/runtime-core/src/components/BaseTransition.ts +++ b/packages/runtime-core/src/components/BaseTransition.ts @@ -473,7 +473,11 @@ function emptyPlaceholder(vnode: VNode): VNode | undefined { function getKeepAliveChild(vnode: VNode): VNode | undefined { return isKeepAlive(vnode) - ? vnode.children + ? // #7121 ensure get the child component subtree in case + // it's been replaced during HMR + __DEV__ && vnode.component + ? vnode.component.subTree + : vnode.children ? ((vnode.children as VNodeArrayChildren)[0] as VNode) : undefined : vnode From a2d810eb40cef631f61991ca68b426ee9546aba0 Mon Sep 17 00:00:00 2001 From: edison Date: Thu, 9 Nov 2023 17:20:54 +0800 Subject: [PATCH 05/42] fix(compiler-core): avoid rewriting scope variables in inline for loops (#7245) close #7238 --- .../transformExpressions.spec.ts.snap | 42 +++++++++++++++++++ .../transforms/transformExpressions.spec.ts | 36 ++++++++++++++++ packages/compiler-core/src/babelUtils.ts | 13 ++++++ 3 files changed, 91 insertions(+) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap index 504c866e128..434ebcbcf2f 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap @@ -13,3 +13,45 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options) + \\" \\" + _toDisplayString($setup.isNaN), 1 /* TEXT */)) }" `; + +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for loop 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock(\\"div\\", { + onClick: () => { + for (let i = 0; i < _ctx.list.length; i++) { + _ctx.log(i) + } + } + }, null, 8 /* PROPS */, [\\"onClick\\"])) +}" +`; + +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock(\\"div\\", { + onClick: () => { + for (const x in _ctx.list) { + _ctx.log(x) + } + } + }, null, 8 /* PROPS */, [\\"onClick\\"])) +}" +`; + +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...of 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock(\\"div\\", { + onClick: () => { + for (const x of _ctx.list) { + _ctx.log(x) + } + } + }, null, 8 /* PROPS */, [\\"onClick\\"])) +}" +`; diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts index f8b82396b08..16229113656 100644 --- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts @@ -534,6 +534,42 @@ describe('compiler: expression transform', () => { expect(code).toMatchSnapshot() }) + test('should not prefix temp variable of for...in', () => { + const { code } = compileWithBindingMetadata( + `
` + ) + expect(code).not.toMatch(`_ctx.x`) + expect(code).toMatchSnapshot() + }) + + test('should not prefix temp variable of for...of', () => { + const { code } = compileWithBindingMetadata( + `
` + ) + expect(code).not.toMatch(`_ctx.x`) + expect(code).toMatchSnapshot() + }) + + test('should not prefix temp variable of for loop', () => { + const { code } = compileWithBindingMetadata( + `
` + ) + expect(code).not.toMatch(`_ctx.i`) + expect(code).toMatchSnapshot() + }) + test('inline mode', () => { const { code } = compileWithBindingMetadata( `
{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }} {{ isNaN }}
`, diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index b52ce28990a..1f1e3896a1e 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -165,6 +165,19 @@ export function walkBlockDeclarations( ) { if (stmt.declare || !stmt.id) continue onIdent(stmt.id) + } else if ( + stmt.type === 'ForOfStatement' || + stmt.type === 'ForInStatement' || + stmt.type === 'ForStatement' + ) { + const variable = stmt.type === 'ForStatement' ? stmt.init : stmt.left + if (variable && variable.type === 'VariableDeclaration') { + for (const decl of variable.declarations) { + for (const id of extractIdentifiers(decl.id)) { + onIdent(id) + } + } + } } } } From 6e0b068e92a70b092d18323c04925e22f8e8456b Mon Sep 17 00:00:00 2001 From: Nebula Date: Thu, 9 Nov 2023 17:21:38 +0800 Subject: [PATCH 06/42] chore: add name option for Teleport (#7315) --- packages/runtime-core/src/components/Teleport.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index cbb77c53516..b9413598e54 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -63,6 +63,7 @@ const resolveTarget = ( } export const TeleportImpl = { + name: 'Teleport', __isTeleport: true, process( n1: TeleportVNode | null, From 657476dcdb964be4fbb1277c215c073f3275728e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F?= <2553241022@qq.com> Date: Thu, 9 Nov 2023 17:32:21 +0800 Subject: [PATCH 07/42] fix(reactivity): clear method on readonly collections should return undefined (#7316) --- packages/reactivity/__tests__/readonly.spec.ts | 16 ++++++++++++++++ .../reactivity/__tests__/shallowReadonly.spec.ts | 12 ++++++++++++ packages/reactivity/src/collectionHandlers.ts | 6 +++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/readonly.spec.ts b/packages/reactivity/__tests__/readonly.spec.ts index d0c91f0fb9f..448419d3176 100644 --- a/packages/reactivity/__tests__/readonly.spec.ts +++ b/packages/reactivity/__tests__/readonly.spec.ts @@ -275,6 +275,14 @@ describe('reactivity/readonly', () => { expect(isReactive(value)).toBe(true) } }) + + test('should return undefined from Map.clear() call', () => { + const wrapped = readonly(new Collection()) + expect(wrapped.clear()).toBeUndefined() + expect( + `Clear operation failed: target is readonly.` + ).toHaveBeenWarned() + }) } }) }) @@ -332,6 +340,14 @@ describe('reactivity/readonly', () => { expect(isReadonly(v2)).toBe(true) } }) + + test('should return undefined from Set.clear() call', () => { + const wrapped = readonly(new Collection()) + expect(wrapped.clear()).toBeUndefined() + expect( + `Clear operation failed: target is readonly.` + ).toHaveBeenWarned() + }) } }) }) diff --git a/packages/reactivity/__tests__/shallowReadonly.spec.ts b/packages/reactivity/__tests__/shallowReadonly.spec.ts index 79d4376cc01..b6736f4a595 100644 --- a/packages/reactivity/__tests__/shallowReadonly.spec.ts +++ b/packages/reactivity/__tests__/shallowReadonly.spec.ts @@ -113,6 +113,12 @@ describe('reactivity/shallowReadonly', () => { ).not.toHaveBeenWarned() }) }) + + test('should return undefined from Map.clear() call', () => { + const sroMap = shallowReadonly(new Map()) + expect(sroMap.clear()).toBeUndefined() + expect(`Clear operation failed: target is readonly.`).toHaveBeenWarned() + }) }) describe('collection/Set', () => { @@ -197,5 +203,11 @@ describe('reactivity/shallowReadonly', () => { ).not.toHaveBeenWarned() }) }) + + test('should return undefined from Set.clear() call', () => { + const sroSet = shallowReadonly(new Set()) + expect(sroSet.clear()).toBeUndefined() + expect(`Clear operation failed: target is readonly.`).toHaveBeenWarned() + }) }) }) diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index 1d07af3be8c..fe7d13d1841 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/packages/reactivity/src/collectionHandlers.ts @@ -223,7 +223,11 @@ function createReadonlyMethod(type: TriggerOpTypes): Function { toRaw(this) ) } - return type === TriggerOpTypes.DELETE ? false : this + return type === TriggerOpTypes.DELETE + ? false + : type === TriggerOpTypes.CLEAR + ? undefined + : this } } From 0e1e8f919e5a74cdaadf9c80ee135088b25e7fa3 Mon Sep 17 00:00:00 2001 From: Rudy Date: Thu, 9 Nov 2023 17:40:36 +0800 Subject: [PATCH 08/42] fix(types): fix instance type when props type is incompatible with setup returned type (#7338) close #5885 --- packages/dts-test/defineComponent.test-d.tsx | 25 +++++++++++++++++++ .../runtime-core/src/apiDefineComponent.ts | 3 +-- .../src/componentPublicInstance.ts | 6 ++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/dts-test/defineComponent.test-d.tsx b/packages/dts-test/defineComponent.test-d.tsx index 7466249e10f..b3f735ddad9 100644 --- a/packages/dts-test/defineComponent.test-d.tsx +++ b/packages/dts-test/defineComponent.test-d.tsx @@ -1472,6 +1472,31 @@ describe('slots', () => { expectType(new comp2().$slots) }) +// #5885 +describe('should work when props type is incompatible with setup returned type ', () => { + type SizeType = 'small' | 'big' + const Comp = defineComponent({ + props: { + size: { + type: String as PropType, + required: true + } + }, + setup(props) { + expectType(props.size) + return { + size: 1 + } + } + }) + type CompInstance = InstanceType + + const CompA = {} as CompInstance + expectType(CompA) + expectType(CompA.size) + expectType(CompA.$props.size) +}) + import { DefineComponent, ComponentOptionsMixin, diff --git a/packages/runtime-core/src/apiDefineComponent.ts b/packages/runtime-core/src/apiDefineComponent.ts index 272bb548751..092f679e966 100644 --- a/packages/runtime-core/src/apiDefineComponent.ts +++ b/packages/runtime-core/src/apiDefineComponent.ts @@ -70,8 +70,7 @@ export type DefineComponent< true, {}, S - > & - Props + > > & ComponentOptionsBase< Props, diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index b7ef1e07302..6ef0c1b9ff2 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -15,7 +15,8 @@ import { isString, isFunction, UnionToIntersection, - Prettify + Prettify, + IfAny } from '@vue/shared' import { toRaw, @@ -187,7 +188,6 @@ export type CreateComponentPublicInstance< I, S > - // public properties exposed on the proxy, which is used as the render context // in templates (as `this` in the render option) export type ComponentPublicInstance< @@ -226,7 +226,7 @@ export type ComponentPublicInstance< : (...args: any) => any, options?: WatchOptions ): WatchStopHandle -} & P & +} & IfAny>> & ShallowUnwrapRef & UnwrapNestedRefs & ExtractComputedReturns & From 34b5a5da4ae9c9faccac237acd7acc8e7e017571 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 10 Nov 2023 12:04:22 +0800 Subject: [PATCH 09/42] fix(hydration): properly hydrate indeterminate prop close #7476 --- packages/runtime-core/__tests__/hydration.spec.ts | 14 ++++++++++++++ packages/runtime-core/src/hydration.ts | 10 ++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index 50331d0623f..e54960222c4 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -953,6 +953,20 @@ describe('SSR hydration', () => { expect((container.firstChild as any)._trueValue).toBe(true) }) + test('force hydrate checkbox with indeterminate', () => { + const { container } = mountWithHydration( + '', + () => + createVNode( + 'input', + { type: 'checkbox', indeterminate: '' }, + null, + PatchFlags.HOISTED + ) + ) + expect((container.firstChild as any).indeterminate).toBe(true) + }) + test('force hydrate select option with non-string value bindings', () => { const { container } = mountWithHydration( '', diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index b8940e6679a..0e94495878e 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -321,23 +321,25 @@ export function createHydrationFunctions( const { type, props, patchFlag, shapeFlag, dirs, transition } = vnode // #4006 for form elements with non-string v-model value bindings // e.g.