用事件委托监听父容器并结合data-id定位,可实现ERP表单“选一项、显一区、关其余”的干净抗扩展逻辑——避免为每个radio写单独事件和硬编码ID判断。
直接用事件委托监听父容器,再通过 data-id 或 data-target 定位关联区域,就能把 erp 表单里“选一项、显一区、关其余”的逻辑写得干净又抗扩展——不用为每个单选按钮写单独事件,也不用硬编码 id 判断。
为什么传统 ERP 表单控制容易崩
很多老系统用类似这样的写法:
- 每个 radio 写
onclick="showForm('newCustomer')",函数里一堆if/else控制显隐 - 新增一个选项就得改 HTML + 改 JS 函数,漏一处就卡死
- 表单状态没统一管理,用户切回上一步时 DOM 显示错乱
- data-* 属性写成
data-user_id或data-UserId,JS 读取失败却查不出原因
核心重构:用 data-id 绑定 + 事件委托接管
HTML 结构保持语义清晰,所有控制逻辑收口到一处 JS:
- radio 元素统一加
data-id="formA",值对应目标容器的id - 目标表单容器用标准
id,初始只留默认项可见,其余加style="display:none" - 监听父容器(比如
form#customerForm)的change事件,不绑定到每个 radio 上 - 在事件回调里用
e.target.dataset.id拿到目标 ID,再用document.getElementById()显隐
关键细节处理(ERP 场景特需)
企业级应用不是 demo,得扛住真实业务压力:
-
兼容 SSR 渲染:泛微、简道云等平台常服务端输出 HTML,此时
dataset可能未初始化,优先用e.target.getAttribute('data-id') -
支持下划线命名:如果后端模板生成的是
data-form_key="import",dataset.formKey读不到,必须用getAttribute('data-form_key') -
防重复触发:radio 的
change在 IE/Edge 旧版可能多次触发,加节流或用checked状态双重校验 -
联动清空字段:显示新表单前,对已展开的其他表单执行
reset()或手动清空 input 值,避免脏数据残留
Vue/React 项目里的注意事项
别以为写了 data-id 就万事大吉:
- Vue 模板中
<input type="radio" data-id="abc">不会自动变成组件 props,事件里仍要从$event.target取 - React 中 JSX 的
data-id是合法属性,但若用useState管理表单显隐,记得把data-id和 state key 对齐,否则重渲染后映射断开 - 泛微 OA 这类 jQuery 遗留系统,推荐用
jQuery(document).on('change', '[name="customerType"]', handler),避免动态插入的 radio 失效

















