@@ -10,6 +10,7 @@ import {
1010 render ,
1111 serializeInner ,
1212 shallowRef ,
13+ watch ,
1314} from '@vue/runtime-test'
1415
1516describe ( 'api: template refs' , ( ) => {
@@ -179,6 +180,89 @@ describe('api: template refs', () => {
179180 expect ( el . value ) . toBe ( null )
180181 } )
181182
183+ // #12639
184+ it ( 'update and unmount child in the same tick' , async ( ) => {
185+ const root = nodeOps . createElement ( 'div' )
186+ const el = ref ( null )
187+ const toggle = ref ( true )
188+ const show = ref ( true )
189+
190+ const Comp = defineComponent ( {
191+ emits : [ 'change' ] ,
192+ props : [ 'show' ] ,
193+ setup ( props , { emit } ) {
194+ watch (
195+ ( ) => props . show ,
196+ ( ) => {
197+ emit ( 'change' )
198+ } ,
199+ )
200+ return ( ) => h ( 'div' , 'hi' )
201+ } ,
202+ } )
203+
204+ const App = {
205+ setup ( ) {
206+ return {
207+ refKey : el ,
208+ }
209+ } ,
210+ render ( ) {
211+ return toggle . value
212+ ? h ( Comp , {
213+ ref : 'refKey' ,
214+ show : show . value ,
215+ onChange : ( ) => ( toggle . value = false ) ,
216+ } )
217+ : null
218+ } ,
219+ }
220+ render ( h ( App ) , root )
221+ expect ( el . value ) . not . toBe ( null )
222+
223+ show . value = false
224+ await nextTick ( )
225+ expect ( el . value ) . toBe ( null )
226+ } )
227+
228+ it ( 'set and change ref in the same tick' , async ( ) => {
229+ const root = nodeOps . createElement ( 'div' )
230+ const show = ref ( false )
231+ const refName = ref ( 'a' )
232+
233+ const Child = defineComponent ( {
234+ setup ( ) {
235+ refName . value = 'b'
236+ return ( ) => { }
237+ } ,
238+ } )
239+
240+ const Comp = {
241+ render ( ) {
242+ return h ( Child , {
243+ ref : refName . value ,
244+ } )
245+ } ,
246+ updated ( this : any ) {
247+ expect ( this . $refs . a ) . toBe ( null )
248+ expect ( this . $refs . b ) . not . toBe ( null )
249+ } ,
250+ }
251+
252+ const App = {
253+ render ( ) {
254+ return show . value ? h ( Comp ) : null
255+ } ,
256+ }
257+
258+ render ( h ( App ) , root )
259+ expect ( refName . value ) . toBe ( 'a' )
260+
261+ show . value = true
262+ await nextTick ( )
263+ expect ( refName . value ) . toBe ( 'b' )
264+ } )
265+
182266 it ( 'unset old ref when new ref is absent' , async ( ) => {
183267 const root1 = nodeOps . createElement ( 'div' )
184268 const root2 = nodeOps . createElement ( 'div' )
0 commit comments