vue使用slot时子组件的onUpdated执行问题
在使用 Vue 的插槽 (slot) 功能时,可能会遇到一个问题:当父组件的任何状态更新时,子组件的
onUpdated
事件会被触发。这个问题在使用默认插槽时尤为明显。
为了避免这种情况,可以使用作用域插槽。
示例代码
以下是一个示例,展示了如何使用默认插槽和作用域插槽。
父组件 (slot.vue
)
<template>
<div class="about">
<h1>{{ msg }}</h1>
<SlotChild class="parentClass">
this is slot content;
<!-- 注释下一行就不会触发onupdated -->
<slot></slot>
<!-- 作用域插槽 可以访问子组件的状态 -->
<template #s2="scope">
hello slot1
{{ scope.text }}
</template>
</SlotChild>
</div>
</template>
<script setup>
import SlotChild from './SlotChild.vue'
import { ref, onUpdated } from 'vue'
const msg = ref('this is messages')
onUpdated(() => {
console.log('updated parent')
})
setTimeout(() => {
msg.value = 'changed msg'
}, 1000)
</script>
子组件 (SlotChild.vue
)
<template>
<div class="about">
<h1>SlotChild</h1>
<slot name="default">
this is default content
</slot>
<!-- 具名插槽,在一个组件里有多个插槽出口 -->
<p>
<slot name="s1" :text='text1'></slot><br>
<slot name="s2" :text='text2'></slot><br>
</p>
</div>
</template>
<script setup>
import { ref, onUpdated } from 'vue'
const text = ref('this is default text')
const text1 = ref('this is scoped text1')
onUpdated(() => {
console.log('updated child')
})
</script>
图片示例
示例代码
github-vue3-learn
解释
在上面的示例中,父组件 slot.vue
使用了默认插槽和作用域插槽。默认插槽会导致子组件在父组件状态更新时触发 onUpdated
事件。而作用域插槽则不会有这个问题,因为它们只会在相关的插槽内容发生变化时才会更新。
根据 Vue 官方文档的解释,作用域插槽允许我们将数据从子组件传递到父组件,从而避免不必要的更新。
通过使用作用域插槽,可以更好地控制组件的更新行为,避免不必要的性能开销。
参考资料
- Vue.js 官方文档 - 插槽
- Vue.js 官方文档 - 作用域插槽