1
- import { remove , isDef , isArray } from 'shared/util'
1
+ import {
2
+ remove ,
3
+ isDef ,
4
+ hasOwn ,
5
+ isArray ,
6
+ isFunction ,
7
+ invokeWithErrorHandling ,
8
+ warn
9
+ } from 'core/util'
2
10
import type { VNodeWithData } from 'typescript/vnode'
11
+ import { Component } from 'typescript/component'
12
+ import { isRef } from 'v3'
3
13
4
14
export default {
5
15
create ( _ : any , vnode : VNodeWithData ) {
@@ -17,28 +27,66 @@ export default {
17
27
}
18
28
19
29
export function registerRef ( vnode : VNodeWithData , isRemoval ?: boolean ) {
20
- const key = vnode . data . ref
21
- if ( ! isDef ( key ) ) return
30
+ const ref = vnode . data . ref
31
+ if ( ! isDef ( ref ) ) return
22
32
23
33
const vm = vnode . context
24
- const ref = vnode . componentInstance || vnode . elm
34
+ const refValue = vnode . componentInstance || vnode . elm
35
+ const value = isRemoval ? null : refValue
36
+
37
+ if ( isFunction ( ref ) ) {
38
+ invokeWithErrorHandling ( ref , vm , [ value ] , vm , `template ref function` )
39
+ return
40
+ }
41
+
42
+ const setupRefKey = vnode . data . ref_key
43
+ const isFor = vnode . data . refInFor
44
+ const _isString = typeof ref === 'string' || typeof ref === 'number'
45
+ const _isRef = isRef ( ref )
25
46
const refs = vm . $refs
26
- const obj = refs [ key ]
27
- if ( isRemoval ) {
28
- if ( isArray ( obj ) ) {
29
- remove ( obj , ref )
30
- } else if ( obj === ref ) {
31
- refs [ key ] = undefined
32
- }
33
- } else {
34
- if ( vnode . data . refInFor ) {
35
- if ( ! isArray ( obj ) ) {
36
- refs [ key ] = [ ref ]
37
- } else if ( obj . indexOf ( ref ) < 0 ) {
38
- obj . push ( ref )
47
+
48
+ if ( _isString || _isRef ) {
49
+ if ( isFor ) {
50
+ const existing = _isString ? refs [ ref ] : ref . value
51
+ if ( isRemoval ) {
52
+ isArray ( existing ) && remove ( existing , refValue )
53
+ } else {
54
+ if ( ! isArray ( existing ) ) {
55
+ if ( _isString ) {
56
+ refs [ ref ] = [ refValue ]
57
+ setSetupRef ( vm , ref , refs [ ref ] )
58
+ } else {
59
+ ref . value = [ refValue ]
60
+ if ( setupRefKey ) refs [ setupRefKey ] = ref . value as any
61
+ }
62
+ } else if ( ! existing . includes ( refValue ) ) {
63
+ existing . push ( refValue )
64
+ }
65
+ }
66
+ } else if ( _isString ) {
67
+ if ( isRemoval && refs [ ref ] !== refValue ) {
68
+ return
39
69
}
70
+ refs [ ref ] = value
71
+ setSetupRef ( vm , ref , value )
72
+ } else if ( _isRef ) {
73
+ if ( isRemoval && ref . value !== refValue ) {
74
+ return
75
+ }
76
+ ref . value = value
77
+ if ( setupRefKey ) refs [ setupRefKey ] = value
78
+ } else if ( __DEV__ ) {
79
+ warn ( `Invalid template ref type: ${ typeof ref } ` )
80
+ }
81
+ }
82
+ }
83
+
84
+ function setSetupRef ( { _setupState } : Component , key : string , val : any ) {
85
+ if ( _setupState && hasOwn ( _setupState , key ) ) {
86
+ if ( isRef ( _setupState [ key ] ) ) {
87
+ _setupState [ key ] . value = val
40
88
} else {
41
- refs [ key ] = ref
89
+ _setupState [ key ] = val
42
90
}
43
91
}
44
92
}
0 commit comments