DEBUG.WIKI
OnlineSIM:在线接收短信,虚拟号码租用
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
野草云;香港 200Mbps 峰值;不限月流量 · BGP VPS;查看套餐 →

Svelte 取消表单 reset,绑定值仍被清空:检查真实点击路径

在 Svelte 5.57.2 中,点击 reset 按钮再于 onreset 取消,可能仍重置绑定状态。把确认放到 reset 之前,并分别检查真实点击与脚本调用。

表单的 onreset 已调用 preventDefault(),用户点击重置按钮后,输入框和绑定状态却仍恢复初值。若脚本调用 form.reset() 时取消又能生效,检查真实点击触发的事件时序。

Svelte 5.57.2 中,下面这类组合仍有问题:

<form onreset={(event) => event.preventDefault()}>
  <input bind:value={text} />
  <button type="reset">重置</button>
</form>

text 应沿用组件已有的状态声明。这段只展示绑定与取消的位置,不是独立组件。问题针对浏览器真实用户输入路径;用控制台调用或脚本点击得到正常结果,不足以排除。

DOM 没有原生重置,不代表框架状态没重置

Svelte 会在 document 的捕获阶段收到 reset 事件,并安排一个微任务,稍后检查 defaultPrevented、调用表单控件的绑定重置处理。

真实用户输入分发时,微任务检查可能发生在目标表单的 onreset 之前。此时事件尚未被取消,绑定状态已被重置;之后即使浏览器取消原生重置,状态回写仍会清空控件。脚本调用 reset 时分发过程有脚本栈,微任务运行的时机不同,因而出现两种入口表现不一致。

排查时同时记录控件值和组件状态。若只是原生 defaultValue 与初始状态设置不一致,应先处理自己的初始化,不能仅凭“重置后值不对”认定是该时序缺口。

有确认流程时,在触发 reset 前决定

如果 reset 的目的就是“确认后才清空”,可把这项交互改为普通按钮:明确写 type="button",由点击处理先完成确认或业务检查;取消时直接返回,通过后再在该处理里调用目标表单的 reset()。

这样取消分支根本不派发 reset 事件,不依赖 onreset 抢在微任务前执行。保留原本需要在真实重置时运行的事件逻辑,并避免仍有一个会无条件取消 reset 的处理器挡住已确认操作。异步确认期间还要防止重复点击和表单已卸载后继续访问节点。

普通按钮不能省略 type,否则放在表单里可能默认提交。也不要把修复写成逐项给输入框赋空字符串:checkbox、select、初值及其他绑定有各自重置语义,手工清空会改变行为。

如果应用需要支持任何来源的 reset 事件都可在 onreset 中取消,按钮绕行并不能修复该公共契约。保留限制,等待并核对覆盖真实用户事件的正式框架修正;不要在框架内部到处添加延时。

用用户真正的操作验收

保留文字、checkbox 和已有初值,分别用真实鼠标或键盘激活按钮,检查取消后 DOM 与状态都不变,确认后两边都恢复正确值。再检查表单正常提交、脚本重置和组件卸载后的行为。

5.57.2 的正式重置监听仍使用捕获阶段加 Promise 微任务,不能把关于修复的设想当作已发行结果。升级后仍应保留真实交互检查,只有脚本 reset 通过并不能证明原来的取消路径恢复。