Svelte列表更新时如何禁止组件回收,正确销毁对应组件实例
问题原因
Svelte的{#each}块默认按列表索引做元素diff,不会追踪数据项的唯一身份。删除索引为1的Orange项时,Svelte对比前后列表长度发现少了1项,会默认复用前3个位置的组件实例,把新的props更新到对应位置的实例上,最后销毁多出来的第4个位置的实例——也就是原本挂载Avocado的组件,因此控制台打印的销毁日志是Avocado,中间位置的组件仅props被更新为Tomato、Avocado,不会触发销毁逻辑。
代码里model = model的写法确实可以强制触发响应式更新,但更规范的实现是直接使用返回新数组的不可变操作方法,比如model = model.filter(item => item.title !== 'Orange'),不需要先splice再重新赋值。
解决方案
给{#each}块指定唯一key值,告知Svelte每个数据项的唯一标识,列表变更时Svelte即可精准匹配对应组件实例,删除数据项时直接销毁对应的组件。
修改后的循环渲染代码:
{#each model as item (item.id)} <Item {...item}></Item> {/each}
括号内的item.id就是key值,示例数据中id为全局唯一字段,完全满足key的要求。添加key后再点击删除按钮,控制台会正确打印Destroyed: Orange,行为符合预期。
内容的提问来源于stack exchange,提问作者Nikolay Dyankov
相关产品推荐
相关产品推荐

