1
1
import { type Ref , customRef , ref } from '@vue/reactivity'
2
2
import { EMPTY_OBJ , camelize , hasChanged , hyphenate } from '@vue/shared'
3
3
import type { DefineModelOptions , ModelRef } from '../apiSetupHelpers'
4
- import { getCurrentInstance } from '../component'
4
+ import {
5
+ type ComponentInternalInstance ,
6
+ getCurrentGenericInstance ,
7
+ } from '../component'
5
8
import { warn } from '../warning'
6
9
import type { NormalizedProps } from '../componentProps'
7
10
import { watchSyncEffect } from '../apiWatch'
@@ -23,14 +26,14 @@ export function useModel(
23
26
name : string ,
24
27
options : DefineModelOptions = EMPTY_OBJ ,
25
28
) : Ref {
26
- const i = getCurrentInstance ( ) !
29
+ const i = getCurrentGenericInstance ( ) !
27
30
if ( __DEV__ && ! i ) {
28
31
warn ( `useModel() called without active instance.` )
29
32
return ref ( ) as any
30
33
}
31
34
32
35
const camelizedName = camelize ( name )
33
- if ( __DEV__ && ! ( i . propsOptions [ 0 ] as NormalizedProps ) [ camelizedName ] ) {
36
+ if ( __DEV__ && ! ( i . propsOptions ! [ 0 ] as NormalizedProps ) [ camelizedName ] ) {
34
37
warn ( `useModel() called with prop "${ name } " which is not declared.` )
35
38
return ref ( ) as any
36
39
}
@@ -65,19 +68,38 @@ export function useModel(
65
68
) {
66
69
return
67
70
}
68
- const rawProps = i . vnode ! . props
69
- if (
70
- ! (
71
- rawProps &&
72
- // check if parent has passed v-model
73
- ( name in rawProps ||
74
- camelizedName in rawProps ||
75
- hyphenatedName in rawProps ) &&
76
- ( `onUpdate:${ name } ` in rawProps ||
77
- `onUpdate:${ camelizedName } ` in rawProps ||
78
- `onUpdate:${ hyphenatedName } ` in rawProps )
79
- )
80
- ) {
71
+
72
+ let rawPropKeys
73
+ let parentPassedModelValue = false
74
+ let parentPassedModelUpdater = false
75
+
76
+ if ( i . rawKeys ) {
77
+ // vapor instance
78
+ rawPropKeys = i . rawKeys ( )
79
+ } else {
80
+ const rawProps = ( i as ComponentInternalInstance ) . vnode ! . props
81
+ rawPropKeys = rawProps && Object . keys ( rawProps )
82
+ }
83
+
84
+ if ( rawPropKeys ) {
85
+ for ( const key of rawPropKeys ) {
86
+ if (
87
+ key === name ||
88
+ key === camelizedName ||
89
+ key === hyphenatedName
90
+ ) {
91
+ parentPassedModelValue = true
92
+ } else if (
93
+ key === `onUpdate:${ name } ` ||
94
+ key === `onUpdate:${ camelizedName } ` ||
95
+ key === `onUpdate:${ hyphenatedName } `
96
+ ) {
97
+ parentPassedModelUpdater = true
98
+ }
99
+ }
100
+ }
101
+
102
+ if ( ! parentPassedModelValue || ! parentPassedModelUpdater ) {
81
103
// no v-model, local update
82
104
localValue = value
83
105
trigger ( )
0 commit comments