Proxy 的 set 拦截器配合字段级 Setter 可实现真正响应式、可追溯、低耦合的表单联动;关键在于每次赋值即触发联动,精准控制依赖与更新边界。
用 Proxy 的
拦截器配合字段级 Setter 逻辑,能实现真正响应式、可追溯、低耦合的表单联动。关键不在“加 setter”,而在于让每次赋值都成为联动触发点,并精准控制依赖关系和更新边界。
联动起点:用 set trap 捕获每一次字段变更
Proxy 的
是唯一能在属性写入**瞬间**介入的机制。比如用户修改手机号,不等失焦、不靠事件监听,只要执行
,就立刻进入联动流程。
必须用
完成真实赋值,否则字段不会存入,且易引发无限递归
禁止在
中直接改其他字段(如
),否则会再次触发
,形成隐式链式调用
推荐把整个代理对象(即
)传给联动函数——这样“确认密码”校验时能读
,“省市区”联动时能读
联动逻辑:按字段声明依赖关系,而非硬编码条件
每个字段应明确声明它会影响谁、被谁影响。避免写满屏
这类散落逻辑。
在初始化时定义联动映射,例如:
在
中查表获取受影响字段列表,再逐个触发其对应的联动函数(如
)
联动函数内部只做数据计算或异步拉取,不操作 DOM 或直接改 state——保持纯逻辑层分离
联动精度:区分“值变”与“需重算”,避免无效刷新
连续输入时,
可能每敲一个字符就触发一次。但“北京”→“北京市”→“北京市朝”并不都需要重算区县列表。
用
做脏检查,跳过无实质变化的赋值
对字符串类字段,可约定仅当长度变化 ≥2 或内容差异超过阈值(如 Levenshtein 距离)才触发深层联动
异步联动(如根据身份证号查籍贯)必须返回 Promise 并单独处理,不可阻塞
同步流程;UI 层通过
状态反馈
联动边界:限制作用域,防止跨模块污染
联动不是越“智能”越好,失控的自动同步反而导致调试困难和状态漂移。
只代理表单数据对象本身(如
),不要代理整个 Vue 组件或 React state 对象
禁用对元字段的写入,例如:
嵌套结构(如
)需递归代理,或统一扁平化为
字段名,避免 Proxy 无法捕获深层赋值
setsetform.phone = "138..."Reflect.set(target, key, value, receiver)settarget.area = "华北"setreceiverreceiver.passwordreceiver.provinceif (key === 'province') { updateCityList() }form.__deps = { province: ['city', 'district'], city: ['district'] }setupdateCityList(form)setObject.is(oldValue, newValue) === falseset$$loading{ name, email, province }if (key.startsWith('$$') || key === '__deps') return trueaddress.cityaddress_city