$slots/useSlots reactivity breaks if same component with different content
Vue version
3.2.37 | @8edf4b3
Link to minimal reproduction
Steps to reproduce
Changing reactively the template for a slot with the same child component but with different content breaks reactivity of useSlots
/$slots
/setup context slots
:
<script setup>
import { ref } from 'vue'
import Comp from './Comp.vue'
import Comp3 from './Comp3.vue'
const data = ref(0)
setInterval(() => {
data.value++
}, 1000)
</script>
<template>
<h1>{{ data }}</h1>
<!-- BUG? Doesn't update properly -->
<Comp3>
<template v-if="data % 2 === 0" #actions>
<Comp>
<template #foo>
{{ data }}
</template>
</Comp>
</template>
<template v-else #actions>
<Comp>
<template #foo>
</template>
</Comp>
</template>
</Comp3>
</template>
What is expected?
The computed calling slots.foo
should be re-evaluated when the content changes.
What is actually happening?
It's not updated and the computed value is stuck.
System Info
No response
Any additional comments?
Related: Slots improvements RFC
due to the diff algorithm, you should add unique keys to differentiate these two <Comp>
<Comp3>
<template v-if="data % 2 === 0" #actions>
<Comp key="1">
<template #foo>
{{ data }}
</template>
</Comp>
</template>
<template v-else #actions>
<Comp key="2">
<template #foo>
</template>
</Comp>
</template>
</Comp3>
Here is a better example.
Glad to see this closed, but the fix 00036bb seems to break vuepress build. After downgrading vue version to 3.2.37, the error disappeared. Does this change affect template syntax?
Repro 1 is not resolved by the fix
Repro 1's root cause is that slots
isn't reactive, similar to attrs
.
Workaround example using a manual ref
for fooSlot
and update it in onBeforeUpdate
(see Comp.vue
)