表单配置里最难维护的常常不是字段多而是一条规则同时承担了计算、网络请求和界面切换。后来换一套组件库连优惠计算也跟着重写。所谓“留白”在这里是给各层明确的责任规则说明数据怎样变化依赖图决定计算顺序视图负责让人操作。WebMCP的声明式API尝试把HTML表单描述成Agent可理解的工具。这仍是提案与试验中的能力。它让一个老问题变得更突出表单的业务意义如果全藏在组件内部人和Agent都只能猜。从三行金额计算开始假设商品总价和优惠金额都是已经确认的整数分值。总价变化先计算优惠再计算应付。界面输入不能直接改应付金额应付也不应偷偷发起下一次请求。图中A→B→C表示一条无环计算依赖。底部回路是“用户修改状态后重新计算”的应用流程与计算图中的循环依赖是两回事。import assert from node:assert/strict; function calculate(input) { for (const key of [subtotal, discount]) { if (!Number.isSafeInteger(input[key]) || input[key] 0) throw new TypeError(amount must be non-negative integer cents); } const appliedDiscount Math.min(input.discount, input.subtotal); return Object.freeze({ subtotal: input.subtotal, appliedDiscount, payable: input.subtotal - appliedDiscount }); } function present(result) { return { payableText: (result.payable / 100).toFixed(2), warning: result.appliedDiscount 100 ? 优惠未达到示例额度 : }; } const state { subtotal: 12345, discount: 100 }; const result calculate(state); assert.equal(present(result).payableText, 122.45); assert.deepEqual(state, { subtotal: 12345, discount: 100 }); assert.equal(calculate({ subtotal: 50, discount: 100 }).payable, 0); assert.throws(() calculate({ subtotal: NaN, discount: 0 }), TypeError); console.log(headless form rule checks passed);规则函数不读DOM也不依赖当前语言展示函数把金额变成字符串。这个拆分不代表规则天然能够“100%跨端共享”税制、舍入方式、时区、权限和服务端定价仍可能让两端职责不同。前端计算只辅助预览最终金额应由交易后端确认。把扩展点放在变化真正发生的地方组件库差异放到渲染适配器异步联动交给带取消和版本判断的控制层业务规则保留输入输出契约。需要表达式时使用明确的领域语言及允许的操作不能用一个eval换取表面上的灵活。10月16日的WebMCP命令式API文档还描述了工具的生命周期与取消。这里可以借用同一个工程习惯作用域结束时解除注册任务取消时停止无用工作。这个原则有用但是否支持某个浏览器API仍需特性检测。本例在Node v26.3.0验证了金额边界、输入不变性和展示输出未运行组件库、浏览器表单或交易后端。它只是能单独检查的一小块规则并不是一套已经上线的表单平台。 SEO 优化官网定制响应式建站教育培训建站