跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何通过 Set 的原始值比较特性实现对复杂表单中重复项的实时高亮提醒

关键在于将表单项标准化为可比较的原始唯一标识(如${name}|${email}|${phone||''}),用Set管理去重,动态维护prevKey实现增删查,并批量更新isDuplicate状态供模板高亮使用。 直接用 Set 判断对象是否重复行不通,因为对象默认按引用比较。要实现复杂表单中重复项的实时高亮提醒,关键在于把每个表单项“标准化为可比较的原始值”,再交由 Set 管理去重逻辑。 提取稳定、可序列化的唯一标识 对每个表单项(如一行输入框组合),需定义一组能代表其业务唯一性的字段,并将它们组合成字符串或数字等原始类型。不能直接用 JSON.stringify(obj),因为属性顺序、空格、undefined 处理不一致,容易误判。 推荐用确定顺序的键名拼接,例如:
`${item.name}|${item.email}|${item.phone || ''}`
对数值或布尔值,统一转为字符串并处理 null/undefined(如转为空字符串或 'null') 若涉及日期,统一格式化为 ISO 字符串(
item.date?.toISOString().slice(0,10)
) 用 Set 存储已出现的标识,并动态更新 维护一个全局 Set 实例,每次用户修改任意字段时,重新计算当前行的标识值,然后检查该值是否已在 Set 中存在。同时,旧标识要从 Set 中移除,新标识加入——这需要记录上一次的标识。 在表单项组件内保存
prevKey
状态,初始为 null 计算新 key 后,先
set.delete(prevKey)
,再
set.add(newKey)
,最后更新
prevKey = newKey
若新 key 已存在(
set.has(newKey) && newKey !== prevKey
),则标记该项为重复 配合响应式状态实现高亮渲染 不要在渲染时反复调用 Set.has(),而应在数据变更后,批量计算每行的
isDuplicate
标志,存入对应项的状态中。这样模板里只需读取布尔值即可。 例如:表单数据结构为
items: { name, email, phone, isDuplicate }[]
每次 change 触发后,遍历 items,为每项生成 key,用 Set 判断是否重复,并更新
isDuplicate
模板中用
class="form-row {{ item.isDuplicate ? 'duplicate' : '' }}"
控制样式 注意边界与性能细节 用户快速连输、粘贴、撤销等操作可能导致中间态混乱,需加防抖或依赖框架的更新时机(如 Vue 的 nextTick、React 的 useEffect)确保 Set 和 UI 同步。 避免在 input 事件中高频执行 Set 操作,可节流至 100ms 内最多一次全量校验 删除某一行时,记得从 Set 中清除其对应的 key 初始化表单时,需遍历原始数据,逐个 add 到 Set,而不是直接 new Set(data.map(...)) —— 因为初始就可能含重复 本质不是靠 Set 多神奇,而是把“人眼认为重复”的逻辑,翻译成机器可比对的原始值。Set 只是高效执行“查重”这个动作的工具。

相关文章