Svelte中如何等待子组件绑定至引用数组?
解决Svelte子组件引用数组未及时填充的问题
当你通过calledFromParent更新data后,Svelte不会同步完成#each循环的子组件渲染与实例绑定,所以此时childs数组仍为空。你尝试的await tick()无效,是因为原函数是同步执行的,没有等待异步的渲染流程完成。
方案一:将calledFromParent改为异步函数
修改组件内的函数为异步,更新data后等待tick(),让Svelte完成组件实例的绑定:
<!-- SomeComponent --> <script> import ChildComponent from './ChildComponent.svelte'; import { tick } from 'svelte'; let data = {childs: []}; let childs = []; export async function calledFromParent(pData) { data = pData; // 等待Svelte完成DOM更新与组件实例绑定 await tick(); console.log(childs.length); // 此时能正确获取子组件实例数量 // 调用子组件方法,比如: // childs.forEach(child => child.someMethod()); } </script> {#each data.childs as child, index} <ChildComponent bind:this={childs[index]}/> {/each}
同时,父组件调用calledFromParent时也需要使用await:
// 父组件中调用的代码 async function loadDataAndCall() { const pData = await fetchYourData(); // 异步加载数据 await someComponentRef.calledFromParent(pData); }
方案二:使用$effect监听数据变化
如果不想修改calledFromParent的调用方式,可以通过$effect监听data的变化,自动触发子组件方法的调用:
<!-- SomeComponent --> <script> import ChildComponent from './ChildComponent.svelte'; import { tick, $effect } from 'svelte'; let data = {childs: []}; let childs = []; export function calledFromParent(pData) { data = pData; } // 监听data变化,完成渲染后处理子组件 $effect(async () => { if (data.childs.length === 0) return; await tick(); console.log(childs.length); // 执行子组件方法逻辑 // childs.forEach(child => child.someMethod()); }); </script> {#each data.childs as child, index} <ChildComponent bind:this={childs[index]}/> {/each}
注意事项
tick()会等待当前所有待处理的DOM更新和组件生命周期完成,确保子组件实例已绑定到childs数组。- 避免使用
setInterval这类不可靠的延迟方式,因为不同环境下渲染耗时不同,容易出现时序问题。
内容的提问来源于stack exchange,提问作者tagomago
相关产品推荐
相关产品推荐

