在Svelte中如何无需修改状态即可撤销用户无效输入并触发组件重渲染?
Svelte 基于编译时依赖收集做 DOM 更新,只有检测到状态值发生实际变更时才会刷新对应绑定的元素,所以才会出现你遇到的无效输入残留问题。可以通过以下三种无冗余状态变更的方案解决需求:
方案1:直接操作DOM(性能最优,推荐)
就是你已经实现的直接修改输入框value的写法,没有多余的重渲染开销,也是Svelte官方推荐的表单场景处理方式:
const handleChange = e => { const userValue = e.target.value; let newValue = userValue? parseInt(userValue): 0; if (isNaN(newValue)) newValue = count; if (newValue === count) { e.target.value = count; } else { count = newValue; } };
方案2:手动调用$$invalidate触发重渲染
如果不想直接操作DOM,可以用Svelte暴露的内部方法$$invalidate,强制标记状态为已变更,哪怕值没有实际变化,也会触发对应DOM更新:
const handleChange = e => { const userValue = e.target.value; let newValue = userValue? parseInt(userValue): 0; if (isNaN(newValue)) newValue = count; count = newValue; // 强制触发count绑定的DOM更新,第一个参数可以传状态名或者编译时分配的索引 $$invalidate('count', count); };
方案3:强制重建输入框元素
如果需要清空输入框的撤销历史、聚焦状态等所有临时状态,可以用{#key}语法配合版本号变量,每次需要重渲染时更新版本号,触发元素销毁重建:
<script> let count = 0; // 版本号,每次更新都会触发{#key}包裹的内容重建 let inputVersion = 0; const handleClick = () => count++; const handleChange = e => { const userValue = e.target.value; let newValue = userValue? parseInt(userValue): 0; if (isNaN(newValue)) newValue = count; count = newValue; inputVersion++; }; </script> Count: <button on:click={handleClick}>{count}</button> <br /> {#key inputVersion} A: <input value={count} on:input={handleChange} /> {/key} <br />
如果你的Svelte版本低于3.48.0,也可以直接给input绑定key属性实现相同效果:<input key={inputVersion} value={count} on:input={handleChange} />
这三种方案都可以替代你现在用的临时赋值NaN的hack写法,符合Svelte的运行机制。
内容的提问来源于stack exchange,提问作者noseratio
相关产品推荐
相关产品推荐

