简体中文 | [English](../../en/develop/3-10-FormItem-introduction.md)
# 用途
- 表单中每个表单项的配置
- 一般只需要配置`type`等少量参数即可使用
- `Form`组件会基于每个`formItem`的配置对输入的数值进行相应的验证
- `Form`验证不通过将无法点击`确认`或`下一步`按钮
# 如何使用
- 每个表单项包含通用型配置
- `name`,表单项的`key`值,必须项,且唯一,表单项的值在验证通过后保存在`form.values[name]`中
- `label`,表单项左侧的标签
- `required`, 可选项,默认值为`false`,值为`true`时为必填项
- `hidden`, 当前表单项是否可隐藏,默认值为`false`
- `onChange`,当前表单项变更时触发的函数
- `extra`,表单想下方的说明文字
- 以创建网络`src/pages/network/containers/Network/actions/CreateNetwork.jsx`为例
```javascript
{
name: 'mtu',
label: t('MTU'),
type: 'input-number',
min: 68,
max: 9000,
extra: t('Minimum value is 68 for IPv4, and 1280 for IPv6.'),
}
```

- `tip`,表单项左侧标签旁边的问号悬停时显示的内容
- 以创建云主机`src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx`为例
```javascript
{
name: 'availableZone',
label: t('Available Zone'),
type: 'select',
placeholder: t('Please select'),
isWrappedValue: true,
required: true,
options: this.availableZones,
tip: t(
'Availability zone refers to a physical area where power and network are independent of each other in the same area. In the same region, the availability zone and the availability zone can communicate with each other in the intranet, and the available zones can achieve fault isolation.'
),
}
```

- `validator`,验证表单的数值是否符合要求
- 返回`Promise`
- 以裸机节点创建端口`src/pages/compute/containers/BareMetalNode/Detail/Port/actions/Create.jsx`为例
```javascript
export const macAddressValidate = (rule, value) => {
if (isMacAddress(value.toUpperCase())) {
return Promise.resolve(true);
}
return Promise.reject(new Error(`${t('Invalid: ')}${macAddressMessage}`));
};
{
name: 'address',
label: t('MAC Address'),
required: true,
type: 'input',
validator: macAddressValidate,
}
```
- `component`,直接使用`component`中的组件,而不是使用`type`配置的组件
- 以云主机修改配置`src/pages/compute/containers/Instance/actions/Resize.jsx`为例
- 直接展示云主机类型选择组件
```javascript
{
name: 'newFlavor',
label: t('Flavor'),
component: (
),
required: true,
wrapperCol: {
xs: {
span: 24,
},
sm: {
span: 18,
},
},
}
```
- `labelCol`,调整表单项标题的布局,默认使用`Form`下定义的标签布局
- 以项目管理配额`src/pages/identity/containers/Project/actions/QuotaManager.jsx`为例
```javascript
{
name: 'instances',
label: t('instance'),
type: 'input-number',
labelCol: { span: 12 },
colNum: 2,
validator: this.checkMin,
}
```

- `wrapperCol`,调整表单项右侧的布局,默认使用`Form`下定义的布局
- 以云主机修改配置`src/pages/compute/containers/Instance/actions/Resize.jsx`为例
- 直接展示云主机类型选择组件
```javascript
{
name: 'newFlavor',
label: t('Flavor'),
component: (
),
required: true,
wrapperCol: {
xs: {
span: 24,
},
sm: {
span: 18,
},
},
}
```

- `style`,定义表单项的样式
- 以创建虚拟网卡`src/pages/network/containers/VirtualAdapter/actions/Create.jsx`为例
```javascript
{
name: 'ipv6',
label: 'IPv6',
type: 'label',
style: { marginBottom: 24 },
content: (
{t('The selected VPC/subnet does not have IPv6 enabled.')}{' '}
{' '}
),
hidden: true,
}
```
- `dependencies`,依赖项,数组,依赖项的数值变动后,会触发当前表单项的验证
- 以云主机更新密码`src/pages/compute/containers/Instance/actions/ChangePassword.jsx`为例
- 确认密码的验证,要依赖于密码的输入
```javascript
{
name: 'confirmPassword',
label: t('Confirm Password'),
type: 'input-password',
dependencies: ['password'],
required: true,
otherRule: getPasswordOtherRule('confirmPassword', 'instance'),
},
```
- `otherRule`,额外的验证规则
- 每个表单根据自己的`type`有独属于自身的配置项,目前支持的`type`有
- `label`
- 展示内容使用
- `iconType`属性,可以显示资源对应的 icon
```javascript
const iconTypeMap = {
instance: ,
router: ,
externalNetwork: ,
network: ,
firewall: ,
volume: ,
gateway: ,
user: ,
snapshot: ,
backup: ,
keypair: ,
image: ImageIcon,
aggregate: ,
metadata: ,
flavor: ,
host: ,
};
```
- 以云主机挂载云硬盘`src/pages/compute/containers/Instance/actions/AttachVolume.jsx`为例
```javascript
{
name: 'instance',
label: t('Instance'),
type: 'label',
iconType: 'instance',
},
```

- `content`属性,默认是基于`name`属性展示内容,如果具有`content`属性,则依照`content`展示内容
- `content`可以是字符串,也可以是 ReactNode
- 以虚拟网卡修改 QoS`src/pages/network/containers/VirtualAdapter/actions/ModifyQoS.jsx`为例
```javascript
{
name: 'name',
label: t('Current QoS policy name'),
type: 'label',
content:
{qosPolicy.name || t('Not yet bound')}
,
hidden: !enableQosPolicy,
}
```
- `input`
- 输入框
- 以编辑镜像`src/pages/compute/containers/Image/actions/Edit.jsx`为例
- 输入系统版本
```javascript
{
name: 'os_version',
label: t('OS Version'),
type: 'input',
required: true,
},
```

- `select`
- 选择
- `options`,必须项,`option`数组,每个`option`需要具有如下属性
- `value`,值
- `label`,展示的文本
- 以创建云主机选择可用域`src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx`为例
```javascript
get availableZones() {
return (globalAvailabilityZoneStore.list.data || [])
.filter((it) => it.zoneState.available)
.map((it) => ({
value: it.zoneName,
label: it.zoneName,
}));
}
{
name: 'availableZone',
label: t('Available Zone'),
type: 'select',
placeholder: t('Please select'),
isWrappedValue: true,
required: true,
options: this.availableZones,
tip: t(
'Availability zone refers to a physical area where power and network are independent of each other in the same area. In the same region, the availability zone and the availability zone can communicate with each other in the intranet, and the available zones can achieve fault isolation.'
),
},
```

- `isWrappedValue`,表示表单项的值中是否要包含`option`信息
- 默认值为`false`,值为选中的`option`中的`value`
- 如果设为`true`,值为选中的`option`
- `divider`
- 横线分隔符
- 以创建云主机`src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx`为例
```javascript
{
type: 'divider',
}
```

- `radio`
- 单选
- `options`,必须项,`option`数组,每个`option`需要具有如下属性
- `value`,值
- `label`,展示的文本
- 以创建云主机选择登陆凭证类型`src/pages/compute/containers/Instance/actions/StepCreate/SystemStep/index.jsx`为例
```javascript
get loginTypes() {
return [
{
label: t('Keypair'),
value: 'keypair',
disabled: this.isWindowsImage,
},
{
label: t('Password'),
value: 'password',
},
];
}
{
name: 'loginType',
label: t('Login Type'),
type: 'radio',
options: this.loginTypes,
isWrappedValue: true,
},
```

- `isWrappedValue`,表示表单项的值中是否要包含`option`信息
- 默认值为`false`,值为选中的`option`中的`value`
- 如果设为`true`,值为选中的`option`
- `select-table`
- 带有选择操作的表格
- `isMulti`,是否是多选,默认为`false`
- `data`,数据源,使用前端分页时使用
- `columns`,表格列的配置,配置方式同`BaseList`
- `filterParams`,搜索项的配置
- `pageSize`,每页条目数量,默认为 5
- `disabledFunc`,判定哪些条目不可选
- `selectedLabel`,表格底部的标签,默认为`已选`
- `header`,表格上方的内容
- `backendPageStore`,使用后端分页时,数据对应的`store`
- `backendPageFunc`,使用后端分页时,获取数据的方法,默认为`fetchListByPage`
- `backendPageDataKey`,使用后端分页时,数据在`store`中的位置,默认为`list`
- `extraParams`,使用后端分页时,发起请求时的额外参数
- `isSortByBack`,是否使用后端排序,默认为`false`
- `defaultSortKey`,使用后端排序时,默认的排序键
- `defaultSortOrder`,使用后端排序时,默认的排序方向
- `initValue`,初始值
- `rowKey`,数据的唯一标识,默认为`id`
- `onRow`,点击条目时的操作,默认点击条目就会选中该条目
- `tabs`,tab 型的表格
- `defaultTabValue`,tab 型表格时,默认的 tab
- `onTabChange`,tab 型表格时,tab 切换时,调用的函数
- 以创建云主机选择安全组`src/pages/compute/containers/Instance/actions/StepCreate/NetworkStep/index.jsx`为例
- 这个表格的右侧标题有 tip 提示
- 使用后端分页的方式展示数据,并具有额外的参数
- 是多选
- 这个表格的上方有额外的展示内容
- 需要复写`onRow`属性,以免点击表格中的`查看规则`按钮时产生操作冲突
```javascript
{
name: 'securityGroup',
label: t('Security Group'),
type: 'select-table',
tip: t(
'Each instance belongs to at least one security group, which needs to be specified when it is created. Instances in the same security group can communicate with each other on the network, and instances in different security groups are disconnected from the internal network by default.'
),
backendPageStore: this.securityGroupStore,
extraParams: { project_id: this.currentProjectId },
required: true,
isMulti: true,
header: (
{t(
'The security group is similar to the firewall function and is used to set up network access control. '
)}
{t(' You can go to the console to ')}
{t('create a new security group')}>{' '}
{t(
'Note: The security group you use will act on all virtual adapters of the instance.'
)}