表单定义
在 Halo 2.0,在 Console 端的所有表单我们都使用了 FormKit 的方案。FormKit 不仅支持使用 Vue 组件的形式来构建表单,同时支持使用 Schema 的形式来构建。因此,我们的 Setting 资源中的表单定义,都是使用 FormKit Schema 来定义的,最常用的场景即主题和插件的设置表单定义。当然,如果要在 Halo 2.0 的插件中使用,也可以参考 FormKit 的文档使用 Vue 组件的形式使用,但不需要在插件中引入 FormKit。
此文档将不会介绍 FormKit 的具体使用教程,因为我们已经很好的集成了 FormKit,并且使用方式基本无异。此文章将介绍 Halo 2.0 中表单定义的一些规范,以及额外的一些输入组件。
FormKit 相关文档:
- Form Schema: https://formkit.com/essentials/schema
- FormKit Inputs: https://formkit.com/inputs
目前不支持 FormKit Pro 中的输入组件,但 Halo 额外提供了部分输入组件,将在下面文档列出。
Setting 资源定义方式
apiVersion: v1alpha1
kind: Setting
metadata:
name: foo-setting
spec:
forms:
- group: group_1
label: 分组 1
formSchema:
- $formkit: radio
name: color_scheme
label: 默认配色
value: system
options:
- label: 跟随系统
value: system
- label: 深色
value: dark
- label: 浅色
value: light
- group: group_2
label: 分组 2
formSchema:
- $formkit: text
name: username
label: 用户名
value: ""
- $formkit: password
name: password
label: 密码
value: ""
需要注意的是,FormKit Schema 本身应该是 JSON 格式的,但目前我们定义一个表单所使用的是 YAML,可能在参考 FormKit 写法时需要手动转换一下。
字段说明:
metadata.name
:设置资源的名称,建议以-setting
结尾。spec.forms
:表单定义,可以定义多个表单,每 个表单都有一个group
字段,用于区分不同的表单。spec.forms[].label
:表单的标题。spec.forms[].formSchema
:表单的定义,使用 FormKit Schema 来定义。虽然我们使用的 YAML,但与 FormKit Schema 完全一致。
组件类型
除了 FormKit 官方提供的常用输入组件之外,Halo 还额外提供了一些输入组件,这些输入组件可以在 Form Schema 中使用。
select
描述
自定义的选择器组件,支持静态和动态数据源,支持多选等功能。
参数
options
:静态数据源。当action
存在时,此参数无效。action
:远程动态数据源的接口地址。requestOption
: 动态数据源的请求参数,可以通过此参数来指定如何获取数据,适配不同的接口。当action
存在时,此参数有效。remoteOptimize
:是否开启远程数据源优化,默认为true
。开启后,将会对远程数据源进行优化,减少请求次数。仅在动态数据源下有效。allowCreate
:是否允许创建新选项,默认为false
。仅在静态数据源下有效。clearable
:是否允许清空选项,默认为false
。multiple
:是否多选,默认为false
。maxCount
:多选时最大可选数量,默认为Infinity
。仅在多选时有效。sortable
:是否支持拖动排序,默认为false
。仅在多选时有效。searchable
: 是否支持搜索,默认为false
。
参数类型定义
{
options?: Array<
Record<string, unknown> & {
label: string;
value: string;
}
>;
action?: string;
requestOption?: {
method?: "GET" | "POST";
/**
* 请求结果中 page 的字段名,默认为 `page`。
*/
pageField?: PropertyPath;
/**
* 请求结果中 size 的字段名,默认为 `size`。
*/
sizeField?: PropertyPath;
/**
* 请求结果中 total 的字段名,默认为 `total`。
*/
totalField?: PropertyPath;
/**
* 从请求结果中解析数据的字段名,默认为 `items`。
*/
itemsField?: PropertyPath;
/**
* 从 items 中解析出 label 的字段名,默认为 `label`。
*/
labelField?: PropertyPath;
/**
* 从 items 中解析出 value 的字段名,默认为 `value`。
*/
valueField?: PropertyPath;
};
remoteOptimize?: boolean;
allowCreate?: boolean;
clearable?: boolean;
multiple?: boolean;
maxCount?: number;
sortable?: boolean;
searchable?: boolean;
}
静态数据示例
- $formkit: select
name: countries
label: What country makes the best food?
sortable: true
multiple: true
clearable: true
searchable: true
placeholder: Select a country
options:
- label: China
value: cn
- label: France
value: fr
- label: Germany
value: de
- label: Spain
value: es
- label: Italy
value: ie
- label: Greece
value: gr
远程动态数据示例
支持远程动态数据源,通过 action
和 requestOption
参数来指定如何获取数据。
请求的接口将会自动拼接 page
、size
与 keyword
参数,其中 keyword
为搜索关键词。
- $formkit: select
name: postName
label: Choose an post
clearable: true
action: /apis/api.console.halo.run/v1alpha1/posts
requestOption:
method: GET
pageField: page
sizeField: size
totalField: total
itemsField: items
labelField: post.spec.title
valueField: post.metadata.name
当远程数据具有分页时,可能会出现默认选项不在第一页的情况,此时 Select 组件将会发送另一个查询请求,以获取默认选项的数据。此接口会携带如下参数:
fieldSelector: `${requestOption.valueField}=(value1,value2,value3)`
其中,value1, value2, value3 为默认选项的值。返回值与查询一致,通过 requestOption
解析。