Svelte开发Todo应用报错:tasks.set is not a function
Svelte Store Todo应用报错排查:tasks.set is not a function
错误原因
当你在App.svelte的{#each $tasks as task}循环中使用bind:value={task.value}时,Svelte会尝试直接修改Store内数组元素的属性。这种绑定逻辑默认会调用Store的set方法,但你自定义的tasks Store并没有暴露set方法,因此触发了TypeError: tasks.set is not a function错误。
解决方案
方案1:直接暴露Store的set方法(快速修复)
修改stores.js中返回的Store对象,添加set方法:
import { writable } from "svelte/store"; function list() { const { subscribe, set, update } = writable([]); return { subscribe, set, // 新增暴露set方法 save: () => { update((items) => { localStorage.setItem("items", JSON.stringify(items)); return items; }); }, add: (item) => update((items) => [...items, item]), remove: (item) => update((items) => items.filter((i) => i !== item)), load: () => { const items = JSON.parse(localStorage.getItem("items")); if (items) set(items); }, update, }; } export var tasks = list();
⚠️ 注意:这种方式虽然能解决报错,但直接修改Store内部元素的做法不符合Store的设计规范,Store状态应通过暴露的方法统一修改。
方案2:通过Store的update方法手动更新(推荐)
遵循Svelte Store的最佳实践,通过自定义方法修改状态,避免直接绑定修改:
- 修改
Item.svelte,传入完整task对象并通过update方法修改值:
<script> import { tasks } from "../stores.js"; export let task; function handleInput(e) { const newValue = e.target.value; // 通过update方法更新对应task的value tasks.update(items => items.map(item => item.id === task.id ? { ...item, value: newValue } : item ) ); tasks.save(); } </script> <div> <input value={task.value} on:input={handleInput} /> </div>
- 修改
App.svelte的循环,传递完整task对象:
{#each $tasks as task (task.id)} <Item {task} /> {/each}
额外优化:简化save方法
原save方法通过update执行localStorage存储,其实可以直接获取当前Store值,逻辑更清晰:
save: () => { // 订阅一次Store获取当前值,立即执行后取消订阅 const unsubscribe = subscribe(items => { localStorage.setItem("items", JSON.stringify(items)); }); unsubscribe(); },
内容的提问来源于stack exchange,提问作者can temizyurek
相关产品推荐
相关产品推荐

