Subscribe on changes!

[bug] Template is not updating when passing vnode to Dynamic Component.

avatar
May 12th 2023

Vue version

3.3.1

Link to minimal reproduction

https://play.vuejs.org

Steps to reproduce

Click on button.

What is expected?

Template should update to show

str-add 
str-add 

What is actually happening?

Only str outside of div update to show "str-add". That is:

str
str-add

Any additional comments?

In the space.vue file, the child in the template is calculated using slots.default(). The content of the first child is<div>{{str}}</div>, and when it's passed to component:is, the ShapeFlags is marked as -1, which prevents it from being updated.

I'm not sure if this is a bug or if this approach is unsupported. If I wrap the child with the h function, there is no issue with updating.

<script setup lang="ts">
import { useSlots,computed, h, Fragment } from 'vue'

const slots = useSlots()
const children = computed(() => {
  return slots.default?.() || []
})
function render(child: any) {
  return h(Fragment, child)
}
</script>

<template>
  <template v-for="(child, index) in children" :key="index">
    <component :is="render(child)"></component>
  </template>
</template>

https://play.vuejs.org/

There is already a similar issue(#4903 ) that has been resolved, but this one is slightly different.

avatar
May 12th 2023

Additionally, if I replace the second template in space.vue with a div, an error occurs when I click the button. Like this:

<template>
  <div v-for="(child, index) in children" :key="index">
    <component :is="child"></component>
  </div>
</template>
avatar
May 15th 2023

as a workaround: use child as key

  <template v-for="(child, index) in children" :key="child">
    <component :is="child"></component>
  </template>