forked from vuejs/core
/
componentVModel.ts
85 lines (78 loc) 路 2.51 KB
/
componentVModel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { extend, ShapeFlags } from '@vue/shared'
import { ComponentInternalInstance, ComponentOptions } from '../component'
import { callWithErrorHandling, ErrorCodes } from '../errorHandling'
import { VNode } from '../vnode'
import { popWarningContext, pushWarningContext } from '../warning'
import {
DeprecationTypes,
warnDeprecation,
isCompatEnabled
} from './compatConfig'
export const compatModelEventPrefix = `onModelCompat:`
const warnedTypes = new WeakSet()
export function convertLegacyVModelProps(vnode: VNode) {
const { type, shapeFlag, props, dynamicProps } = vnode
const comp = type as ComponentOptions
if (shapeFlag & ShapeFlags.COMPONENT && props && 'modelValue' in props) {
if (
!isCompatEnabled(
DeprecationTypes.COMPONENT_V_MODEL,
// this is a special case where we want to use the vnode component's
// compat config instead of the current rendering instance (which is the
// parent of the component that exposes v-model)
{ type } as any
)
) {
return
}
if (__DEV__ && !warnedTypes.has(comp)) {
pushWarningContext(vnode)
warnDeprecation(DeprecationTypes.COMPONENT_V_MODEL, { type } as any, comp)
popWarningContext()
warnedTypes.add(comp)
}
// v3 compiled model code -> v2 compat props
// modelValue -> value
// onUpdate:modelValue -> onModelCompat:input
const model = comp.model || {}
applyModelFromMixins(model, comp.mixins)
const { prop = 'value', event = 'input' } = model
if (prop !== 'modelValue') {
props[prop] = props.modelValue
delete props.modelValue
}
// important: update dynamic props
if (dynamicProps) {
dynamicProps[dynamicProps.indexOf('modelValue')] = prop
}
props[compatModelEventPrefix + event] = props['onUpdate:modelValue']
delete props['onUpdate:modelValue']
}
}
function applyModelFromMixins(model: any, mixins?: ComponentOptions[]) {
if (mixins) {
mixins.forEach(m => {
if (m.model) extend(model, m.model)
if (m.mixins) applyModelFromMixins(model, m.mixins)
})
}
}
export function compatModelEmit(
instance: ComponentInternalInstance,
event: string,
args: any[]
) {
if (!isCompatEnabled(DeprecationTypes.COMPONENT_V_MODEL, instance)) {
return
}
const props = instance.vnode.props
const modelHandler = props && props[compatModelEventPrefix + event]
if (modelHandler) {
callWithErrorHandling(
modelHandler,
instance,
ErrorCodes.COMPONENT_EVENT_HANDLER,
args
)
}
}