Svelte动态组件场景重置数组ID后新增首个元素不显示问题问询
问题原因
这个问题是Svelte 3的{#each}循环diff机制和key重复共同导致的:
如果你没有给{#each}循环显式指定key,Svelte默认按元素索引匹配,本身就容易出现组件复用异常。就算你已经用元素id作为key,清空数组后重置id,新生成的id=1的元素和之前销毁的旧id=1元素会被Svelte判定为同一个实例。由于旧实例已经被标记为销毁状态,Svelte就不会渲染这个新的同key元素。取消id重置后key不会重复,问题自然消失。
解决方案
方案1:给key加版本标识(最推荐,完全不影响业务逻辑)
给两个数组分别配套加一个版本号变量,每次清空数组时同时把对应版本号+1,修改{#each}的key为id加版本号的组合值,确保即使id重置,全局key唯一:
<script> let boxes1 = [] let id1 = 1 let version1 = 0 // 新增boxes1对应的版本号 let boxes2 = [] let id2 = 1 let version2 = 0 // 新增boxes2对应的版本号 function clearBoxes1() { boxes1 = [] id1 = 1 version1 += 1 // 清空时版本号+1 } // boxes2的清空逻辑同理 </script> <!-- 修改each的key为组合值 --> {#each boxes1 as item ( `${item.id}-${version1}` )} <svelte:component this={item.comp} {...item.props} /> {/each}
方案2:清空数组时错开更新队列
如果不想改key逻辑,可以在清空数组后加一个微任务延迟重置id,避开Svelte同一批更新队列的diff判断:
async function clearBoxes1() { boxes1 = [] // 等待当前更新队列执行完毕、所有旧组件完全销毁后再重置id await Promise.resolve() id1 = 1 }
这个方案改动量更小,不会影响普通业务场景的使用。
内容的提问来源于stack exchange,提问作者anotherempty
相关产品推荐
相关产品推荐

