
本文介绍如何使用 derived 和 get 创建一个响应式派生 store,将单个可写 store 的值与一个包含多个 store 的数组合并为扁平化数值数组,并强调此类嵌套 store 设计的潜在陷阱。
本文介绍如何使用 `derived` 和 `get` 创建一个响应式派生 store,将单个可写 store 的值与一个包含多个 store 的数组合并为扁平化数值数组,并强调此类嵌套 store 设计的潜在陷阱。
在 Svelte 中,若需将一个基础 store(如 writable(1))与“store 的数组”(如 [writable(2), writable(3)])合并为单一扁平数组 [1, 2, 3],直接解构订阅无法自动响应内层 store 的变化——因为 derived 仅监听其显式依赖项(即 a 和 b 本身),而不会追踪 b 内部各 store 的更新。
正确做法是:在 derived 回调中,用 get() 主动读取每个内层 store 的当前值,并手动拼接:
import { writable, derived, get } from 'svelte/store';
const a = writable(1);
const b = writable([writable(2), writable(3)]);
const combined = derived([a, b], ([$a, $b]) => {
return [$a, ...$b.map(store => get(store))];
});✅ 输出效果:
$combined始终为[1, 2, 3](初始值),且当a或b被重新赋值时(例如b.set([writable(4), writable(5)])),combined会重新计算。
⚠️ 重要警告:此模式存在严重局限性
-
b是一个存储 store 实例的数组,但derived不会响应其内部 store 的.set()调用(如b[0].set(99))。因为b的引用未变,derived不会重新执行。 - 这违背了 Svelte 响应式设计原则:store 应封装状态,而非作为“状态容器的容器”。
✅ 推荐替代方案
将所有状态统一管理于一个可写 store 中,或使用 derived 组合多个独立 store(避免 store 嵌套):
// 更健壮的设计:扁平化依赖 const a = writable(1); const b0 = writable(2); const b1 = writable(3); const combined = derived([a, b0, b1], ($values) => $values); // [1, 2, 3]
或使用 derived 动态聚合多个独立 store(需明确列出):
const stores = [a, b0, b1]; const combined = derived(stores, $stores => $stores);
总之,get() 可解决“一次性读取”需求,但无法实现真正响应式嵌套;生产环境应规避 store 嵌套,优先采用扁平、显式、可追踪的依赖结构。

















