Svelte中如何实现#each循环响应式更新?对应场景有哪些可行方案?
Svelte each循环响应性问题解答
现有代码的#each语句能否实现响应式运行?
不能默认实现响应式更新。
Svelte的响应式更新依赖显式赋值动作触发检测,如果你在收到新消息时仅调用数组方法修改messages的内部内容(比如直接执行messages.push(newMsg)),Svelte无法感知到数组的变化,each循环就不会重新渲染。
修复/优化方案
方案1:补充赋值触发响应检测(最简方案)
修改数组后补充赋值动作,即可触发Svelte的更新检测,原有each代码无需改动:
// 原有写法(不生效) messages.push(newMsg) // 修改后写法1 messages.push(newMsg) messages = messages // 修改后写法2 更简洁的展开语法 messages = [...messages, newMsg]
方案2:给each添加唯一key(推荐)
如果你的消息列表存在删除、排序等操作,推荐给each循环添加唯一key,减少不必要的组件重渲染,提升性能:
<!-- 这里用消息的唯一id作为key,没有id也可以用 username+发送时间戳 拼接的唯一值 --> {#each messages as msg (msg.id)} <Message username={msg.username} content={msg.content}/> {/each}
方案3:使用响应式存储(适用于跨组件共享数据场景)
如果messages需要在多个组件中访问,可以将其定义为writable store,自动触发响应更新:
首先定义store:
// stores.js import { writable } from 'svelte/store' export const messages = writable([])
组件中使用:
<script> import { messages } from './stores.js' </script> <!-- 用$前缀访问store内容 --> {#each $messages as msg (msg.id)} <Message username={msg.username} content={msg.content}/> {/each}
新增消息时调用store的update方法即可:
messages.update(oldList => [...oldList, newMsg])
内容的提问来源于stack exchange,提问作者mavdotjs
相关产品推荐
相关产品推荐

