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'
210import type { VNodeWithData } from 'typescript/vnode'
11+ import { Component } from 'typescript/component'
12+ import { isRef } from 'v3'
313
414export default {
515 create ( _ : any , vnode : VNodeWithData ) {
@@ -17,28 +27,66 @@ export default {
1727}
1828
1929export 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
2232
2333 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 )
2546 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
3969 }
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
4088 } else {
41- refs [ key ] = ref
89+ _setupState [ key ] = val
4290 }
4391 }
4492}
0 commit comments