Skip to content

Commit 2be828a

Browse files
authored
fix(runtime-vapor): handle v-model vdom interop error (#13643)
1 parent fca74b0 commit 2be828a

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

packages/runtime-core/src/renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2727,7 +2727,7 @@ export function traverseStaticChildren(
27272727
function locateNonHydratedAsyncRoot(
27282728
instance: ComponentInternalInstance,
27292729
): ComponentInternalInstance | undefined {
2730-
const subComponent = instance.subTree.component
2730+
const subComponent = instance.vapor ? null : instance.subTree.component
27312731
if (subComponent) {
27322732
if (subComponent.asyncDep && !subComponent.asyncResolved) {
27332733
return subComponent

packages/runtime-vapor/__tests__/vdomInterop.spec.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1-
import { createVNode, defineComponent, h, renderSlot } from '@vue/runtime-dom'
1+
import {
2+
createVNode,
3+
defineComponent,
4+
h,
5+
nextTick,
6+
ref,
7+
renderSlot,
8+
toDisplayString,
9+
useModel,
10+
} from '@vue/runtime-dom'
211
import { makeInteropRender } from './_utils'
3-
import { createComponent, defineVaporComponent } from '../src'
12+
import {
13+
applyTextModel,
14+
child,
15+
createComponent,
16+
defineVaporComponent,
17+
renderEffect,
18+
setText,
19+
template,
20+
} from '../src'
421

522
const define = makeInteropRender()
623

@@ -26,6 +43,54 @@ describe('vdomInterop', () => {
2643
})
2744
})
2845

46+
describe('v-model', () => {
47+
test('basic work', async () => {
48+
const VaporChild = defineVaporComponent({
49+
props: {
50+
modelValue: {},
51+
modelModifiers: {},
52+
},
53+
emits: ['update:modelValue'],
54+
setup(__props) {
55+
const modelValue = useModel(__props, 'modelValue')
56+
57+
const n0 = template('<h1> </h1>')() as any
58+
const n1 = template('<input>')() as any
59+
const x0 = child(n0) as any
60+
applyTextModel(
61+
n1,
62+
() => modelValue.value,
63+
_value => (modelValue.value = _value),
64+
)
65+
renderEffect(() => setText(x0, toDisplayString(modelValue.value)))
66+
return [n0, n1]
67+
},
68+
})
69+
70+
const { html, host } = define({
71+
setup() {
72+
const msg = ref('foo')
73+
return () =>
74+
h(VaporChild as any, {
75+
modelValue: msg.value,
76+
'onUpdate:modelValue': (value: string) => {
77+
msg.value = value
78+
},
79+
})
80+
},
81+
}).render()
82+
83+
expect(html()).toBe('<h1>foo</h1><input>')
84+
85+
const inputEl = host.querySelector('input')!
86+
inputEl.value = 'bar'
87+
inputEl.dispatchEvent(new Event('input'))
88+
89+
await nextTick()
90+
expect(html()).toBe('<h1>bar</h1><input>')
91+
})
92+
})
93+
2994
describe('emit', () => {
3095
test('emit from vapor child to vdom parent', () => {
3196
const VaporChild = defineVaporComponent({

0 commit comments

Comments
 (0)