Subscribe on changes!

Async components are lost from $refs after a state update

avatar
Feb 7th 2021

Version

3.0.5

Reproduction link

https://codepen.io/gfeher/pen/VwmaRVq

Steps to reproduce

Click on the "click me!" button two or more times.

What is expected?

After the first click, the following message should appear:

Can I see $refs.promisedComponent? YES
Can I see $refs.regularComponent? YES

After the second and subsequent clicks, the message should stay the same as above.

What is actually happening?

After the first click, the message is as it's expected. However, after the second and subsequent clicks, it changes to the following:

Can I see $refs.promisedComponent? NO
Can I see $refs.regularComponent? YES

I am looking into migration from Vue 2 to Vue 3: in the real life code in which I have discovered this problem, I was trying to use async imports with webpack instead of the promise-based hack in the codepen. It was like this:

import RegularComponent from './regular-component.vue';

export default {
...
  components: {
    PromisedComponent: defineAsyncComponent(() => import('./promised-component.vue')),
    RegularComponent
  }
}
avatar
Feb 8th 2021

Note you should be using flush: 'post' in your watcher (https://v3.vuejs.org/guide/reactivity-computed-watchers.html#effect-flush-timing) which makes the thing consistently fail

avatar
Feb 10th 2021

When using the template ref on async component:

<AsyncComp ref="myRef" />

This ref will be forwarded to the inner component, ideally, the inner component should take over the ref completely, but it will be set to null every time an async component is patched, see the setRef function.

Therefor, this PR makes the inner component completely take over the template ref forwarded from the async component

avatar
Feb 10th 2021

@HcySunYang I've pulled your branch into my project and it seems to be fixing my original issue.

avatar
Mar 14th 2021

I think the fix is not yet included in 3.0.7 according to the changelog.

avatar
Mar 14th 2021

Sorry, I seem to have responded to a deleted comment.

avatar
Mar 14th 2021

Yes, it was merged after 3.0.7 and will be part of 3.0.8