使用 NForm
基本使用
NForm 组件可以通过传入 fields 和 data 来快速构建出一个典型的表单, 该组件还可以通过 fieldLayout 自定义布局.
fields 属性说明
fields 属性用于描述表单中的表单项结构. 该属性是一个由 FormModelFieldArgs 组成的数组.
当
FormModelFieldArgs是一个对象时, 其name属性是必填且唯一的, 用于描述表单项的名称(也会被作为key体现在data属性中).以下是可选参数:
label: 表单项的标签文本type: 表单项的控件类型, 如输入框/选择框等initialValue: 表单项控件的初始值, 重置表单时会使用该值做为表单的初始值.TIP
该值会被作为
data属性中的初始值, 但是当data属性中对应的值不为undefined/null时, 该值会被忽略.- modifiers: 修饰符, 用于修饰表单项控件, 如
trim修饰符会对输入框的值进行去除首尾空格的处理.
javascriptconst field = { name: "name", // 必填且唯一 label: "标签", type: FormItemControlType.INPUT, // 默认为 FormItemControlType.INPUT initialValue: "初始值", // 表单项的初始值 modifiers: { trim: true } // 修饰符 };当
FormModelFieldArgs是一个数组时, 数组的第一项同上, 第二项是一个对象, 其中设置的属性会直接传递给表单项控件(即 type 属性对应的 Ant Design Vue 组件). 当仅用对象参数不能够满足需求时, 可以通过该方式传递额外的参数给表单项控件.javascriptconst field = [ { name: "name", // 必填且唯一 label: "标签", type: FormItemControlType.SELECT, // 默认为 FormItemControlType.INPUT initialValue: "option1" // 表单项的初始值 }, { options: [ { label: "option1", value: "option1" }, { label: "option2", value: "option2" }, { label: "option3", value: "option3" } ] // 为选择框添加选项 } ];
data 属性说明
data 属性需要传入一个 ref 对象, 用于存储表单数据. 该对象的初始值可以为空对象, 也可以是一个包含表单项初始值的对象. 支持通过 v-model:data 双向绑定表单数据.
vue
<script>
import { ref } from "vue";
const data = ref({});
</script>
<template>
<NForm v-model:data="data" />
</template>自定义表单项值的存储方式
默认情况下表单项的值会以 name 属性为键值存储在 data 中, 但也可以通过 valueMapTo 属性自定义值的存储方式. 示例见 自定义值的存储方式
FormItemControlType 与 Ant Design Vue 组件的对应关系
FormItemControlType 是一个枚举类型, 用于描述表单项的类型, NForm 内置了 ant-design-vue 的 13 种表单项类型, 如下表格所示.
| 类型 | 描述 | ant-design-vue 组件 | 自定义组件 |
|---|---|---|---|
| INPUT | 输入框 | Input | |
| INPUT_NUMBER | 数字输入框 | - | NInputNumber |
| SELECT | 下拉框 | Select | |
| DATE_PICKER | 日期选择器 | DatePicker | |
| DATE_RANGE_PICKER | 日期范围选择器 | DateRangePicker | |
| TIME_PICKER | 时间选择器 | TimePicker | |
| TIME_RANGE_PICKER | 时间范围选择器 | TimeRangePicker | |
| SWITCH | 开关 | Switch | |
| RADIO_GROUP | 单选框 | RadioGroup | |
| CHECKBOX_GROUP | 多选框 | CheckboxGroup | |
| TEXT_AREA | 文本域 | TextArea | |
| SLIDER | 滑块 | Slider | |
| TREE_SELECT | 树选择器 | TreeSelect | |
| CASCADER | 级联选择器 | Cascader |
vue
<script setup>
import { ref, watch } from "vue";
import { NForm, useAntDesignVueFormHelper, FormItemControlType } from "@nbicc/common-components";
const data = ref({});
const fields = ref([
{ name: "input", label: "输入框输入框输入框输入框", type: FormItemControlType.INPUT },
{ name: "input-number", label: "数字输入框", type: FormItemControlType.INPUT_NUMBER },
[
{ name: "select", label: "下拉框", type: FormItemControlType.SELECT },
{
options: [
{ label: "option1", value: "option1" },
{ label: "option2", value: "option2" },
{ label: "option3", value: "option3" }
]
}
],
{ name: "date-picker", label: "日期选择器", type: FormItemControlType.DATE_PICKER },
{ name: "time-picker", label: "时间选择器", type: FormItemControlType.TIME_PICKER },
{ name: "switch", label: "开关", type: FormItemControlType.SWITCH },
[
{ name: "radio", label: "单选框", type: FormItemControlType.RADIO_GROUP },
{
options: [
{ label: "option1", value: "option1" },
{ label: "option2", value: "option2" },
{ label: "option3", value: "option3" }
]
}
],
[
{ name: "checkbox", label: "多选框", type: FormItemControlType.CHECKBOX_GROUP },
{
options: [
{ label: "option1", value: "option1" },
{ label: "option2", value: "option2" },
{ label: "option3", value: "option3" }
]
}
],
{ name: "textarea", label: "文本域", type: FormItemControlType.TEXT_AREA },
{ name: "slider", label: "滑块", type: FormItemControlType.SLIDER },
{ name: "tree-select", label: "树选择器", type: FormItemControlType.TREE_SELECT },
{ name: "cascader", label: "级联选择器", type: FormItemControlType.CASCADER }
]);
watch(data, () => console.log(data.value));
</script>
<template>
<NForm v-model:data="data" :fields="fields"></NForm>
</template>控制表单项布局
NForm 可通过 fieldLayout 属性控制表单项的布局. fieldLayout 集合了 Ant Design Vue 的 Row 和 Col 组件的 props, 除此之外还提供了 fields 属性, 用于单独指定某个表单项的布局.
- 为每个表单项设置 span 为 12, 但给 name 为
input的表单项设置 span 为 24配置
javascriptconst fieldLayout = { span: 12, fields: { input: { span: 24 } } }; - 为每个表单项设置 span 为 12 且具有
8px的间隔.配置
javascriptconst fieldLayout = { span: 12, gutter: 8 };
vue
<template>
<NForm
:fields="[
{ name: 'input', label: '输入框输入框输入框输入框', type: FormItemControlType.INPUT },
{ name: 'input-number', label: '数字输入框', type: FormItemControlType.INPUT_NUMBER },
{ name: 'textarea', label: '文本域', type: FormItemControlType.TEXT_AREA }
]"
:fieldLayout="{ span: 12, gutter: 16, fields: { textarea: { span: 24 } } }"
></NForm>
</template>设置 label 的宽度
自定义整个表单的 label 宽度
NForm 继承了 Ant Design Vue Form 组件的所有属性,可以通过 labelCol 属性来设置 label 宽度。
vue
<template>
<NForm
:fields="[
{ name: 'input', label: '输入框输入框输入框输入框', type: FormItemControlType.INPUT },
{ name: 'input-number', label: '数字输入框', type: FormItemControlType.INPUT_NUMBER }
]"
:label-col="{ flex: '100px' }"
></NForm>
</template>自定义表单项的 label 宽度
fields 属性中的每个表单项都支持 Ant Design Vue FormItem 组件的所有属性. 因此可以通过 labelCol 属性来设置指定表单项 label 宽度。
TIP
如果在 NForm 和 fields 中都指定了 labelCol 属性, 优先使用 fields 中的 labelCol 属性.
vue
<template>
<NForm
:fields="[
{
name: 'input',
label: '输入框输入框输入框输入框',
type: FormItemControlType.INPUT,
labelCol: { flex: '100px' }
},
{ name: 'input-number', label: '数字输入框', type: FormItemControlType.INPUT_NUMBER }
]"
></NForm>
</template>设置表单项状态
NForm 通过 fieldStatus 属性设置表单项的禁用/只读状态. fieldStatus 属性接收一个对象, 可以通过 disabled 统一设置表单项的禁用状态, 通过 readOnly 统一设置表单项的只读状态. 也可以通过 fields 属性单独设置某个表单项的禁用/只读状态.
- 为每个表单项设置禁用状态, 但给 name 为
input的表单项设置只读状态配置
javascriptconst fieldStatus = { disabled: true, fields: { input: { disabled: false, readOnly: true } } };