fix(compat): handle v-model deprecation warning with missing appContext (#14203)

close #14202
This commit is contained in:
edison 2025-12-18 16:14:53 +08:00 committed by GitHub
parent dfe667c856
commit 945a543152
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 1 deletions

View File

@ -1,5 +1,6 @@
import { ShapeFlags, extend } from '@vue/shared' import { ShapeFlags, extend } from '@vue/shared'
import type { ComponentInternalInstance, ComponentOptions } from '../component' import type { ComponentInternalInstance, ComponentOptions } from '../component'
import { createAppContext } from '../apiCreateApp'
import { ErrorCodes, callWithErrorHandling } from '../errorHandling' import { ErrorCodes, callWithErrorHandling } from '../errorHandling'
import type { VNode } from '../vnode' import type { VNode } from '../vnode'
import { popWarningContext, pushWarningContext } from '../warning' import { popWarningContext, pushWarningContext } from '../warning'
@ -31,7 +32,14 @@ export function convertLegacyVModelProps(vnode: VNode): void {
if (__DEV__ && !warnedTypes.has(comp)) { if (__DEV__ && !warnedTypes.has(comp)) {
pushWarningContext(vnode) pushWarningContext(vnode)
warnDeprecation(DeprecationTypes.COMPONENT_V_MODEL, { type } as any, comp) warnDeprecation(
DeprecationTypes.COMPONENT_V_MODEL,
{
type,
appContext: (vnode.ctx && vnode.ctx.appContext) || createAppContext(),
} as any,
comp,
)
popWarningContext() popWarningContext()
warnedTypes.add(comp) warnedTypes.add(comp)
} }

View File

@ -140,4 +140,41 @@ describe('COMPONENT_V_MODEL', () => {
template: `<input :value="foo" @input="$emit('bar', $event.target.value)">`, template: `<input :value="foo" @input="$emit('bar', $event.target.value)">`,
}) })
}) })
// #14202
test('should handle v-model deprecation warning with missing appContext', async () => {
const ChildComponent = {
template: `<div @click="$emit('input', 'new val')">{{ value }}</div>`,
props: ['value'],
}
const vm = new Vue({
components: { ChildComponent },
data() {
return {
myVal: 'initial',
}
},
template: `
<div>
<child-component v-model="myVal"></child-component>
</div>
`,
}).$mount() as any
expect(vm.$el.textContent).toContain('initial')
expect(
(deprecationData[DeprecationTypes.COMPONENT_V_MODEL].message as Function)(
ChildComponent,
),
).toHaveBeenWarned()
// Should work correctly
const child = vm.$el.querySelector('div')
child.click()
await nextTick()
expect(vm.myVal).toBe('new val')
expect(vm.$el.textContent).toContain('new val')
})
}) })