Svelte中send/receive过渡仅对列表最后一个元素生效问题
Svelte send/receive过渡仅最后一个元素生效的问题修复
问题原因
- #each循环未指定唯一key:当前代码中
#each未显式声明唯一标识key,Svelte默认使用数组索引作为key。当过滤数组时,元素索引会发生变化,Svelte会复用DOM元素而非识别为元素的移除/添加操作,导致send/receive无法正确匹配跨列表的元素,仅最后一个元素因索引唯一变化触发过渡效果。 - 数组修改未遵循不可变性:直接修改原数组元素后,用同一个数组引用更新store,Svelte的响应式系统无法准确检测到数组内容的变化,导致过渡逻辑未被触发。
修复步骤
1. 为#each循环添加唯一key
在两个#each循环中添加(hotel.id)作为key,让Svelte通过唯一ID跟踪元素:
{#each hotels.filter((hotel) => hotel.favourite !== 'true') as hotel (hotel.id)} <div in:receive={{ key: hotel.id }} out:send={{ key: hotel.id }}> <Col xs="3"> <Card class="mb-3"> <CardHeader> <CardTitle>{hotel.name} <i class='bi bi-bag-plus-fill favourite' on:click={() => addFavourite(hotel.id)}></i> </CardTitle> </CardHeader> </Card> </Col> </div> {/each} {#each hotels.filter((hotel) => hotel.favourite === 'true') as hotel (hotel.id)} <div in:receive={{ key: hotel.id }} out:send={{ key: hotel.id }}> <Col xs="3"> <Card class="mb-3"> <CardHeader> <CardTitle>{hotel.name} <i class='bi bi-bag-plus-fill favourite' on:click={() => addFavourite(hotel.id)}></i> </CardTitle> </CardHeader> </Card> </Col> </div> {/each}
2. 修改数组时保持不可变性
更新addFavourite函数,创建新数组而非直接修改原数组,确保store能检测到内容变化:
function addFavourite (hotelId) { // 通过map创建新数组,修改目标元素的favourite属性 const updatedHotels = $hotelList.map(hotel => hotel.id === hotelId ? {...hotel, favourite: 'true'} : hotel ); hotelList.set(updatedHotels); }
额外优化:移除冗余变量
原代码中$: hotels = $hotelList属于冗余声明,可直接使用$hotelList简化代码:
{#if $hotelList && $hotelList.length > 0} <h3>Hotels</h3> <Row> {#each $hotelList.filter((hotel) => hotel.favourite !== 'true') as hotel (hotel.id)} <!-- ... 元素内容 ... --> {/each} </Row> {/if}
内容的提问来源于stack exchange,提问作者Kihaf
相关产品推荐
相关产品推荐

