
本文介绍如何使用 Svelte 的 derived 和 get 函数构建一个响应式派生 Store,将单个值 Store 与包含多个 Store 的数组合并为扁平化数值数组,并重点提醒嵌套 Store 的响应性陷阱。
本文介绍如何使用 svelte 的 `derived` 和 `get` 函数构建一个响应式派生 store,将单个值 store 与包含多个 store 的数组合并为扁平化数值数组,并重点提醒嵌套 store 的响应性陷阱。
在 Svelte 中,有时我们需要将一个基础值 Store(如 writable(1))与一个“Store 的数组”(如 [writable(2), writable(3)])组合成单一、扁平化的数值列表(例如 [1, 2, 3])。虽然 derived 能监听多个 Store 的变化,但它不会自动追踪嵌套 Store 内部的变化——这是关键前提。
要实现目标,需借助 get 函数(来自 svelte/store)在派生逻辑中同步读取每个子 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))];
});
✅ 此写法等价于
[ $a, get($b[0]), get($b[1]) ],并利用展开语法(...)替代.flat(),语义更清晰、性能略优。
⚠️ 重要注意事项:响应性局限
上述方案仅在 a 或 b 本身被赋新值时触发更新(例如 b.set([writable(4), writable(5)])),但若仅修改 b 中某个子 Store(如 b.subscribe(...)[0].set(99)),combined 不会重新计算——因为 b 的引用未变,derived 无法感知其内部 Store 的变化。
✅ 推荐替代方案(真正响应式)
若需对子 Store 变化也保持响应,应避免“Store 套 Store”,改用扁平化数据结构:
const a = writable(1); const bValues = writable([2, 3]); // 存储原始值,非 Store const combined = derived([a, bValues], ([$a, $bVals]) => [$a, ...$bVals]);
或使用 derived 链式订阅子 Store(适用于少量固定子 Store):
const b0 = writable(2); const b1 = writable(3); const combined = derived([a, b0, b1], ([$a, $b0, $b1]) => [$a, $b0, $b1]);
总之:Store 是响应式单元,而非数据容器。将 Store 存入另一个 Store 会破坏响应链路;优先用原始值 + 明确依赖声明,才能获得预期的自动更新行为。










