目录

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: aname: b 的渲染会出现异常,渲染了一个四不像。需要刷新页面才能恢复正常。

正常版本

halo-form-key-1.avif

halo-form-key-2.avif

异常版本

halo-form-key-3.avif

halo-form-key-4.avif

原因

name: aname: 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