如何为每个Svelte子组件实例创建独立Store并嵌套到父组件Store中
为每个子组件实例创建独立Store并嵌套到父组件Store的解决方案
核心问题分析
你当前子组件用<script context="module">导出的childStore是模块级变量,所有子实例会共享同一个Store,不符合“每个实例独立”的需求。要实现目标,需在子组件实例脚本中创建专属Store,并将其传递给父组件存入父Store的数组。
具体修改步骤
1. 修改子组件:创建实例专属Store并传递给父组件
移除模块级脚本,在实例脚本中初始化独立Store,通过回调函数把Store传给父组件:
<script lang="ts"> import { writable, derived, onMount } from 'svelte/store'; export let childIndex: number; // 为当前实例创建独立Store,初始化子组件专属数据 export const childStore = writable<Child>({ index: childIndex, value: 0 }); // 子组件专属计算Store export const calculatedChild = derived(childStore, $store => ({ doubled: $store.value * 2 })); // 定义回调,用于将当前实例的Store传递给父组件 export let onStoreReady: (store: typeof childStore, index: number) => void; // 组件挂载后触发回调,把Store传给父组件 onMount(() => { onStoreReady(childStore, childIndex); }); // 子组件数据类型定义 type Child = { index: number; value: number; }; </script> <div id={childIndex} class="child"> <p>子组件 {childIndex}: 当前值 {$childStore.value} | 双倍值 {$calculatedChild.doubled}</p> <button on:click={() => childStore.update(s => ({...s, value: s.value + 1}))}>+1</button> </div>
2. 修改父组件:接收子组件Store并维护到父Store中
在父组件中定义回调函数接收子组件的Store,更新父Store的childs数组,同时实现基于所有子Store数据的计算逻辑:
<script lang="ts"> import { writable, derived } from 'svelte/store'; import Child from './Child.svelte'; // 类型定义 type Child = { index: number; value: number; }; type ParentState = { childs: ReturnType<typeof writable<Child>>[]; }; export const parentStore = writable<ParentState>({ childs: [] }); // 整合所有子组件数据的计算Store export const calculatedStuff = derived( parentStore, $parent => derived($parent.childs, childStores => { // 计算所有子组件value的总和 const total = childStores.reduce((sum, store) => sum + $store.value, 0); return { totalChildValues: total }; }) ); // 接收子组件传递的Store,更新父Store的childs数组 const handleStoreReady = (store: ReturnType<typeof writable<Child>>, index: number) => { parentStore.update(state => { const newChilds = [...state.childs]; newChilds[index] = store; return { ...state, childs: newChilds }; }); }; // 示例:生成3个子组件 const childrenCount = 3; </script> <div class="parent"> <h2>父组件</h2> <p>所有子组件值总和: {$($calculatedStuff).totalChildValues}</p> {#each Array(childrenCount) as _, childIndex} <Child {childIndex} onStoreReady={handleStoreReady} /> {/each} </div>
关键说明
- 子组件的Store必须在实例脚本(不带
context="module"的<script>)中创建,确保每个组件实例生成独立的Store。 - 通过
onMount触发回调传递Store,保证组件挂载完成后父组件能获取有效实例Store。 - 父组件的
calculatedStuff用嵌套derived,既能监听父Store变化,也能响应每个子Store的更新,实现聚合计算。
内容的提问来源于stack exchange,提问作者Thony
相关产品推荐
相关产品推荐

