Svelte中如何实现嵌套Map的input双向绑定?
实现嵌套Map的输入绑定等效功能
由于Svelte目前不支持直接绑定Map对象的条目,你可以通过手动绑定value属性+监听输入事件实现等效于bind:value={v}的功能,核心思路是:
- 用
value={v}显示Map中的当前值 - 监听输入事件,实时更新对应Map条目
- 重新赋值Map触发Svelte的响应式更新
修改后的完整代码:
<script> import { range } from 'radash'; let myMap = new Map([ [ 2021, new Map([ [1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "e"], [7, "e"], [8, "e"], [9, "e"], [10, "e"], [11, "e"], [12, "e"] ]) ], [ 2022, new Map([ [1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "e"], [7, "e"], [8, "e"], [9, "e"], [10, "e"], [11, "e"], [12, "e"] ]) ], [ 2023, new Map([ [1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "e"], [7, "e"], [8, "e"], [9, "e"], [10, "e"], [11, "e"], [12, "e"] ]) ] ]); function updateValue(year, month, newValue) { // 获取对应年份的子Map const yearMap = myMap.get(year); // 更新月份对应的值 yearMap.set(month, newValue); // 重新赋值Map,触发Svelte响应式更新 myMap = new Map(myMap); } </script> <p>Editable table:</p> <table> <tr> <th></th> {#each Array.from(range(1, 12)) as month} <th>{month}</th> {/each} </tr> {#each myMap.entries() as [year, yearMonth]} <tr> <th>{year}</th> <!-- 解构出month变量,用于定位Map条目 --> {#each yearMonth.entries() as [month, v]} <td> <input type="text" value={v} <!-- 监听input事件,实时更新Map --> on:input={(e) => updateValue(year, month, e.target.value)} style="width: 4em" /> </td> {/each} </tr> {/each} </table> <p>View Table:</p> <table> <tr> <th></th> {#each Array.from(range(1, 12)) as month} <th>{month}</th> {/each} </tr> {#each myMap.entries() as [year, yearMonth]} <tr> <th>{year}</th> {#each yearMonth.entries() as [_, v]} <td> {v} </td> {/each} </tr> {/each} </table>
关键说明:
- 原
bind:value={v}无效的原因:解构出的v是Map条目的值副本,修改它不会同步回Map;同时Svelte无法自动跟踪Map内部的内容变化。 updateValue函数中,修改Map后执行myMap = new Map(myMap)是核心:通过创建新的Map实例,让Svelte检测到引用变化,从而触发视图更新。- 使用
on:input而非on:change,能实现和bind:value一致的实时更新效果。
内容的提问来源于stack exchange,提问作者Stéphane Klein
相关产品推荐
相关产品推荐

