Svelte stores可复用getter提取的最佳实践咨询
解决方案说明
你当前的写法存在一个隐性问题:直接在模板中调用enableAllAllowed()时,内部的get()方法只会单次读取store值,不会订阅store更新,后续依赖的store发生变化时,模板的disabled状态不会自动同步更新,需要优先修正。
可选方案优先级推荐
1. 优先用derived store实现复用(最轻量最优解)
这是最贴合Svelte原生设计的方案,不需要额外封装,自动实现响应式更新,性能也最优:仅当依赖的任意store变更时,才会重新计算getter值。
实现代码如下:
import { derived, get } from 'svelte/store'; // 导出响应式的derived store代替普通函数 export const enableAllAllowed = derived( [storeA, storeB, storeC, storeD], ([$storeA, $storeB, $storeC, $storeD]) => { return $storeA.available && $storeB.available && $storeC.available && $storeD.canEnableAll; } ); export function enableAll() { if (get(enableAllAllowed)) { storeA.update(current => ({ ...current, enabled: true })); storeB.update(current => ({ ...current, enabled: true })); storeC.update(current => ({ ...current, enabled: true })); } }
组件中直接用Svelte的$订阅语法即可,自动响应更新:
<!-- Component1 / Component2 通用写法 --> <button disabled={!$enableAllAllowed} on:click={enableAll}> Enable All </button>
2. 自定义store封装(适合关联逻辑多的场景)
如果你的项目中这类关联store的操作和getter非常多,推荐把相关逻辑合并封装为自定义store,内聚状态和操作方法,避免到处导入零散的store和工具函数:
import { derived, get } from 'svelte/store'; function createToggleStore() { const { subscribe } = derived( [storeA, storeB, storeC, storeD], ([$a, $b, $c, $d]) => ({ enableAllAllowed: $a.available && $b.available && $c.available && $d.canEnableAll, // 其他相关的getter可以统一在这里定义 }) ); return { subscribe, enableAll: () => { const state = get({ subscribe }); if (state.enableAllAllowed) { storeA.update(v => ({ ...v, enabled: true })); storeB.update(v => ({ ...v, enabled: true })); storeC.update(v => ({ ...v, enabled: true })); } } // 其他相关操作方法可以统一在这里定义 } } export const toggleStore = createToggleStore();
组件中使用更简洁,不需要导入多个变量:
<button disabled={!$toggleStore.enableAllAllowed} on:click={toggleStore.enableAll}> Enable All </button>
选型建议
- 如果仅需要复用少量独立getter,直接选
derivedstore方案即可,无额外维护成本 - 如果相关的业务逻辑高度关联、方法和getter数量多,选自定义store方案更利于后续维护
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

