Subscribe on changes!

If a component is loaded by defineAsyncComponent in a block combined with "v-for" "component :is" directives, it always being remounted / rerendered if any state value changed in v-for block (Another minimal reproduction)

avatar
Jun 18th 2021

Version

3.1.1

Reproduction link

https://jsfiddle.net/horseluke/oq4cn3h9/

Steps to reproduce

  1. Open https://jsfiddle.net/horseluke/oq4cn3h9/. This is a minimal reproduction using Vue 3.1.1.
  2. Click button "Just change state that in v-for" after 2 seconds.
  3. Click button "Just change state that in v-for" after 2 seconds again.

What is expected?

  1. In step 2 and step 3, values that showed in "Mount time" and "ComponentSub Id" should not be changed. If not changed, component is not remounted / rerendered.

What is actually happening?

  1. In step 2 and step 3, values that showed in "Mount time" and "ComponentSub Id" which belongs to "Component load with defineAsyncComponent and surrounded by v-for" has been changed. This means components loaded by defineAsyncComponent has been remounted / rerendered.

This is another minimal reproduction that trigger this bug.

To read more: https://github.com/vuejs/vue-next/issues/3977

avatar
Jun 18th 2021

This is because you are calling a function that returns a new async component every time. Async components must be registered in components or passed to a shallowRef():

const AsyncComp = defineAsyncComponent(() =>
  import('./components/AsyncComponent.vue')
)

const currentComponent = shallowRef(AsyncComp)

// then do <component :is="currentComponent" />

More info https://v3.vuejs.org/guide/component-dynamic-async.html#async-components.


Remember to use the forum or the Discord chat to ask questions!

avatar
Jun 18th 2021

OK, thanks!