Vue3中如何监听useSlots()获取的插槽组件props变化?
解决Vue中useSlots()获取插槽props不更新的问题
在Vue 3组件场景中,通过useSlots()获取插槽内容并手动渲染时,会遇到插槽子组件props更新后无法同步的问题——比如点击外部按钮更新name值后,插槽内的Child组件始终显示旧值。
问题原因
你当前在setup阶段仅调用一次slots.default()并缓存结果到defaultSlot变量中,但slots.default()返回的是当前渲染周期的VNode数组,并非响应式对象。当外部props变化时,这个缓存的变量不会自动更新,导致渲染时始终使用旧的props数据。
解决方案
要确保每次渲染都能拿到最新的插槽内容和props,必须将slots.default()的调用逻辑放在render函数内部,而非提前在setup阶段缓存结果。
方案1:直接渲染最新插槽内容
修改Parent组件代码,把插槽获取逻辑移到render函数内:
// Parent component <script setup> import { h, useSlots } from "vue"; const slots = useSlots(); const render = () => { // 每次渲染时获取最新的插槽VNode const defaultSlot = slots.default(); return h("div", {}, defaultSlot); }; </script> <template> <render /> </template>
方案2:手动创建Child组件并传递最新props
如果需要手动实例化Child组件(如你代码中的第一种render写法),同样要在render内获取最新的props:
// Parent component <script setup> import Child from "./Child.vue"; import { h, useSlots } from "vue"; const slots = useSlots(); const render = () => { const defaultSlot = slots.default(); // 每次渲染都取最新的props传递给Child return h("div", {}, h(Child, defaultSlot[0].props)); }; </script> <template> <render /> </template>
原理说明
useSlots()返回的slots对象本身是响应式的,但slots.default()是一个方法,每次调用都会生成对应当前状态的VNode数组。将调用放在render函数内后,Vue会在每次组件更新时重新执行render函数,从而获取到最新的插槽props,确保Child组件能接收到更新后的值。
内容的提问来源于stack exchange,提问作者Nagisa Ando
相关产品推荐
相关产品推荐

