Halo CMS 表单定义的隐藏规则
前言
Halo CMS 文档在表单定义提到了,所有表单都使用了使用 FormKit Schema 来定义。这必然会伴随抽象泄露(Leaky Abstraction)问题——底层实现细节无法被完美隐藏,有时会漏出来影响你。
问题描述
如果你定义了以下的表单(设计意图:switch1 启用时,a 显示,反之 b 显示):
# settings.yaml
spec:
forms:
- group: group1
label: 组标签
formSchema:
- $formkit: switch
name: switch1
label: 开关
value: false
- $formkit: number
name: a
if: "$switch1 === true"
label: 真时显示,number 类型
value: 200
- $formkit: switch
name: b
if: "$switch1 === false"
label: 假时显示,switch 类型
value: true
你会发现当 switch1 切换时,name: a 和 name: b 的渲染会出现异常,渲染了一个四不像。需要刷新页面才能恢复正常。
正常版本:


异常版本:


原因
name: a 和 name: b 会被渲染成同一个 Vue 组件 <FormKit>。当条件发生变化时,Vue 的差异算法看到这个位置上始终是同一个 <FormKit> 组件,就会尽量复用已有的组件实例。
解决办法
类比建议使用 v-for 时添加 key,给每个字段指定一个 key,避免 Vue 意外复用。
修改后如下:
# settings.yaml
spec:
forms:
- group: group1
label: 组标签
formSchema:
- $formkit: switch
name: switch1
label: 开关
value: false
- $formkit: number
name: a
key: a // [!code ++]
if: "$switch1 === true"
label: 真时显示,number 类型
value: 200
- $formkit: switch
name: b
key: c // [!code ++]
if: "$switch1 === false"
label: 假时显示,switch 类型
value: true
总结
定义表单时,建议每个 name: 都配备一个 key:,以避免类似的渲染错误。
类似的渲染错误还容易出现在 array 组件。
0