Skip to content

使用 NForm

基本使用

NForm 组件可以通过传入 fieldsdata 来快速构建出一个典型的表单, 该组件还可以通过 fieldLayout 自定义布局.

fields 属性说明

fields 属性用于描述表单中的表单项结构. 该属性是一个由 FormModelFieldArgs 组成的数组.

  • FormModelFieldArgs 是一个对象时, 其 name 属性是必填且唯一的, 用于描述表单项的名称(也会被作为 key 体现在 data 属性中).

    以下是可选参数:

    1. label: 表单项的标签文本
    2. type: 表单项的控件类型, 如输入框/选择框等
    3. initialValue: 表单项控件的初始值, 重置表单时会使用该值做为表单的初始值.

      TIP

      该值会被作为 data 属性中的初始值, 但是当 data 属性中对应的值不为 undefined/null 时, 该值会被忽略.

    4. modifiers: 修饰符, 用于修饰表单项控件, 如 trim 修饰符会对输入框的值进行去除首尾空格的处理.
    javascript
    const field = {
      name: "name", // 必填且唯一
      label: "标签",
      type: FormItemControlType.INPUT, // 默认为 FormItemControlType.INPUT
      initialValue: "初始值", // 表单项的初始值
      modifiers: { trim: true } // 修饰符
    };
  • FormModelFieldArgs 是一个数组时, 数组的第一项同上, 第二项是一个对象, 其中设置的属性会直接传递给表单项控件(即 type 属性对应的 Ant Design Vue 组件). 当仅用对象参数不能够满足需求时, 可以通过该方式传递额外的参数给表单项控件.

    javascript
    const 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 的 RowCol 组件的 props, 除此之外还提供了 fields 属性, 用于单独指定某个表单项的布局.

  • 为每个表单项设置 span 为 12, 但给 name 为 input 的表单项设置 span 为 24
    配置
    javascript
    const fieldLayout = {
      span: 12,
      fields: {
        input: { span: 24 }
      }
    };
  • 为每个表单项设置 span 为 12 且具有 8px 的间隔.
    配置
    javascript
    const 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 的表单项设置只读状态
    配置
    javascript
    const fieldStatus = {
      disabled: true,
      fields: {
        input: { disabled: false, readOnly: true }
      }
    };
  1. 设置表单项的禁用状态
  2. 设置表单项的只读状态