You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte中如何实现嵌套Map的input双向绑定?

实现嵌套Map的输入绑定等效功能

由于Svelte目前不支持直接绑定Map对象的条目,你可以通过手动绑定value属性+监听输入事件实现等效于bind:value={v}的功能,核心思路是:

  1. 用value={v}显示Map中的当前值
  2. 监听输入事件,实时更新对应Map条目
  3. 重新赋值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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:20:33