File tree Expand file tree Collapse file tree 3 files changed +48
-7
lines changed
Expand file tree Collapse file tree 3 files changed +48
-7
lines changed Original file line number Diff line number Diff line change @@ -14,7 +14,7 @@ import {
1414import { ref } from './apis'
1515import vmStateManager from './utils/vmStateManager'
1616import {
17- updateTemplateRef ,
17+ afterRender ,
1818 activateCurrentInstance ,
1919 resolveScopedSlots ,
2020 asVmProperty ,
@@ -31,16 +31,13 @@ export function mixin(Vue: VueConstructor) {
3131 Vue . mixin ( {
3232 beforeCreate : functionApiInit ,
3333 mounted ( this : ComponentInstance ) {
34- updateTemplateRef ( this )
34+ afterRender ( this )
3535 } ,
3636 beforeUpdate ( ) {
3737 updateVmAttrs ( this as ComponentInstance )
3838 } ,
3939 updated ( this : ComponentInstance ) {
40- updateTemplateRef ( this )
41- if ( this . $vnode ?. context ) {
42- updateTemplateRef ( this . $vnode . context )
43- }
40+ afterRender ( this )
4441 } ,
4542 } )
4643
Original file line number Diff line number Diff line change 1+ import type { VNode } from 'vue'
12import { ComponentInstance } from '../component'
23import vmStateManager from './vmStateManager'
34import {
@@ -76,7 +77,7 @@ export function asVmProperty(
7677 }
7778}
7879
79- export function updateTemplateRef ( vm : ComponentInstance ) {
80+ function updateTemplateRef ( vm : ComponentInstance ) {
8081 const rawBindings = vmStateManager . get ( vm , 'rawBindings' ) || { }
8182 if ( ! rawBindings || ! Object . keys ( rawBindings ) . length ) return
8283
@@ -103,6 +104,19 @@ export function updateTemplateRef(vm: ComponentInstance) {
103104 vmStateManager . set ( vm , 'refs' , validNewKeys )
104105}
105106
107+ export function afterRender ( vm : ComponentInstance ) {
108+ const stack = [ ( vm as any ) . _vnode as VNode ]
109+ while ( stack . length ) {
110+ const vnode = stack . pop ( ) !
111+ if ( vnode . context ) updateTemplateRef ( vnode . context )
112+ if ( vnode . children ) {
113+ for ( let i = 0 ; i < vnode . children . length ; ++ i ) {
114+ stack . push ( vnode . children [ i ] )
115+ }
116+ }
117+ }
118+ }
119+
106120export function updateVmAttrs ( vm : ComponentInstance , ctx ?: SetupContext ) {
107121 if ( ! vm ) {
108122 return
Original file line number Diff line number Diff line change @@ -113,6 +113,36 @@ describe('ref', () => {
113113 //@ts -ignore
114114 expect ( vm . $refs . barRef ) . toBe ( vm . barRef )
115115 } )
116+
117+ it ( 'should update deeply nested component refs using scoped slots' , async ( ) => {
118+ const vm = new Vue ( {
119+ setup ( ) {
120+ const divRef = ref ( null )
121+ const showDiv = ref ( false )
122+ return {
123+ divRef,
124+ showDiv,
125+ }
126+ } ,
127+ template : `<div><foo #default>Slot: <div ref="divRef" v-if="showDiv" /></foo></div>` ,
128+ components : {
129+ foo : {
130+ components : {
131+ bar : {
132+ template : `<div><slot /></div>` ,
133+ } ,
134+ } ,
135+ template : '<div><bar #default><slot /></bar></div>' ,
136+ } ,
137+ } ,
138+ } ) . $mount ( )
139+ await nextTick ( )
140+ //@ts -ignore
141+ vm . showDiv = true
142+ await nextTick ( )
143+ //@ts -ignore
144+ expect ( vm . $refs . divRef ) . toBe ( vm . divRef )
145+ } )
116146 // TODO: how ?
117147 // it('work with createElement', () => {
118148 // let root;
You can’t perform that action at this time.
0 commit comments