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

Svelte删除多个待办项后新增项无法渲染并报错

Svelte待办应用删除多元素后新增失效的问题解决

问题根源

  • 混合Svelte响应式更新与原生DOM操作:你在deleteTodo里手动调用document.getElementById(id).remove(),这会破坏Svelte对DOM的管理逻辑。Svelte依赖todos数组的状态来渲染DOM,手动删除DOM会导致Svelte内部的DOM跟踪和实际页面不一致,后续新增元素时就会抛出removeChild相关错误。
  • 删除逻辑错误:用id-1作为splice的索引,当删除多个元素后,数组元素的索引和id不再一一对应(比如删了id=1的元素,剩余元素id是2、3,但索引变成0、1),此时用id-1操作会删错位置,导致数组状态混乱。

解决方案

  1. 移除手动操作DOM的代码,让Svelte全权负责DOM更新
  2. 修改删除逻辑,通过id找到正确的数组索引再执行删除
  3. 给{#each}添加唯一key,帮助Svelte更准确地跟踪每个待办项

修改后的完整代码

<script>
  let todos = []
  let heading = 'Enter heading here';
  let msg = 'enter your todo here'
  let n = 1;

  function pushTodo(){
    todos = [...todos, new Todo(n, heading, msg)]
    n+=1
    console.log('added todo and increased n to'+ n)
    console.log(todos)
  }

  class Todo{
    constructor(id, title, msg){
      this.id = id
      this.title = title
      this.msg = msg
    }
  }

  function deleteTodo(targetId) {
    // 根据id过滤数组,返回新数组(符合Svelte响应式最佳实践)
    todos = todos.filter(todo => todo.id !== targetId);
    console.log(todos)
  }
</script>

<input type="text" bind:value={heading}>
<input type="text" bind:value={msg}>

<button on:click={pushTodo}>insert todo</button>

{#each todos as {id, title, msg} (id)} <!-- 添加id作为唯一key -->
<div>
  <h6>{id}</h6>
  <h2>{title}</h2>
  <h4>{msg}</h4>
  <button on:click={() => deleteTodo(id)}>delete</button>
</div>
{/each}

关键改动说明

  • 删掉了document.getElementById(id).remove(),完全依赖Svelte的响应式更新来维护DOM
  • 改用filter生成新数组的方式删除元素,避免索引计算错误,同时更契合Svelte的响应式机制
  • 在{#each}循环中添加(id)作为key,Svelte会通过这个唯一标识精准跟踪每个元素的状态,避免渲染混乱

内容的提问来源于stack exchange,提问作者Momen Alany

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:40:25