Skip to content

Form 表单

承载数据录入、校验和提交,是业务系统里最核心的交互容器。

基础用法

等待提交
vue
<template>
  <x-form :model="form" @submit="handleSubmit">
    <x-form-item field="name" tooltip="用于展示在业务列表中" label="名称" required>
      <x-input v-model="form.name" placeholder="请输入名称" />
    </x-form-item>
    <x-form-item field="post" label="职位">
      <x-input v-model="form.post" placeholder="请输入职位" />
    </x-form-item>
    <x-form-item field="isRead">
      <x-checkbox v-model="form.isRead">我已阅读并同意</x-checkbox>
    </x-form-item>
    <x-form-item>
      <x-button type="primary" html-type="submit">提交</x-button>
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive } from 'vue';

const form = reactive({ name: '', post: '', isRead: false });
const handleSubmit = ({ values, errors }) => {
  console.log(values, errors);
};
</script>

布局

vue
<template>
  <x-radio-group v-model="layout" type="button">
    <x-radio value="horizontal">horizontal</x-radio>
    <x-radio value="vertical">vertical</x-radio>
    <x-radio value="inline">inline</x-radio>
  </x-radio-group>
  <x-form :model="form" :layout="layout">
    <x-form-item field="name" label="用户名">
      <x-input v-model="form.name" />
    </x-form-item>
    <x-form-item field="post" label="岗位">
      <x-input v-model="form.post" />
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';

const layout = ref('horizontal');
const form = reactive({ name: '', post: '' });
</script>

表单校验

14/80
点击提交查看校验结果
vue
<template>
  <x-form ref="formRef" :model="form" :rules="rules" scroll-to-first-error @submit="handleSubmit">
    <x-form-item field="name" label="用户名" :validate-trigger="['change', 'input']">
      <x-input v-model="form.name" placeholder="至少 3 个字符" />
    </x-form-item>
    <x-form-item field="age" label="年龄">
      <x-input-number v-model="form.age" :min="0" :max="200" />
    </x-form-item>
    <x-form-item field="section" label="部门">
      <x-select v-model="form.section" :options="sectionOptions" allow-clear />
    </x-form-item>
    <x-form-item>
      <x-button type="primary" html-type="submit">提交校验</x-button>
      <x-button @click="formRef?.resetFields()">重置</x-button>
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';

const formRef = ref();
const form = reactive({ name: '', age: 18, section: '' });
const rules = {
  name: [
    { required: true, message: '请输入用户名' },
    { minLength: 3, message: '用户名至少 3 个字符' },
  ],
  age: [{ type: 'number', max: 120, message: '年龄不能超过 120' }],
  section: [{ match: /section one/, message: '请选择 Section One' }],
};
const sectionOptions = [
  { label: 'Section One', value: 'section one' },
  { label: 'Section Two', value: 'section two' },
];
const handleSubmit = ({ values, errors }) => {
  console.log(values, errors);
};
</script>

表单方法

可手动触发表单方法
vue
<template>
  <x-form ref="formRef" :model="form" :rules="rules">
    <x-form-item field="username" label="用户名">
      <x-input v-model="form.username" />
    </x-form-item>
    <x-form-item field="email" label="邮箱">
      <x-input v-model="form.email" />
    </x-form-item>
    <x-form-item>
      <x-button @click="formRef?.validate()">validate</x-button>
      <x-button @click="setServerError">setFields</x-button>
      <x-button @click="formRef?.clearValidate()">clearValidate</x-button>
      <x-button @click="formRef?.resetFields()">resetFields</x-button>
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';

const formRef = ref();
const form = reactive({ username: '', email: '' });
const rules = {
  username: [{ required: true, message: '请输入用户名' }],
  email: [{ type: 'email', message: '邮箱格式不正确' }],
};
const setServerError = () => {
  formRef.value?.setFields({
    email: { status: 'error', message: '服务端返回:邮箱已被占用' },
  });
};
</script>

状态与反馈

开启 feedback 后,支持的控件会展示反馈图标
Section One
vue
<template>
  <x-form :model="form" :size="size">
    <x-form-item
      field="name"
      label="名称"
      help="当前状态由 validateStatus 手动控制"
      extra="开启 feedback 后展示反馈图标"
      :validate-status="status"
      feedback
    >
      <x-input v-model="form.name" />
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';

const status = ref('success');
const size = ref('medium');
const form = reactive({ name: '' });
</script>

全局禁用

vue
<template>
  <x-form :model="form" disabled>
    <x-form-item field="name" label="用户名">
      <x-input v-model="form.name" />
    </x-form-item>
    <x-form-item field="isRead">
      <x-checkbox v-model="form.isRead">已确认</x-checkbox>
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive } from 'vue';

const form = reactive({ name: 'Locked user', isRead: true });
</script>

帮助信息和插槽

用于后台账号展示
vue
<template>
  <x-form :model="form">
    <x-form-item field="name" required validate-trigger="input">
      <template #label>
        <span>登录名</span>
      </template>
      <x-input v-model="form.name" />
      <template #extra>
        <span>用于后台账号展示</span>
      </template>
    </x-form-item>
    <x-form-item field="post" label="岗位" required>
      <x-input v-model="form.post" />
      <template #help>
        <span>自定义帮助信息会展示在控件下方</span>
      </template>
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive } from 'vue';

const form = reactive({ name: '', post: '' });
</script>

嵌套字段

产品
支持 user.name、members[0] 这类路径
vue
<template>
  <x-form ref="formRef" :model="form" :rules="rules" @submit="handleSubmit">
    <x-form-item field="user.name" label="姓名">
      <x-input v-model="form.user.name" />
    </x-form-item>
    <x-form-item field="user.email" label="邮箱">
      <x-input v-model="form.user.email" />
    </x-form-item>
    <x-form-item field="members" label="成员">
      <x-select v-model="form.members" :options="memberOptions" multiple />
    </x-form-item>
  </x-form>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';

const formRef = ref();
const form = reactive({
  user: { name: '', email: '' },
  members: ['pm'],
});
const rules = {
  'user.name': [{ required: true, message: '请输入姓名' }],
  'user.email': [{ type: 'email', message: '邮箱格式不正确' }],
  members: [{ type: 'array', minLength: 2, message: '至少选择 2 个成员' }],
};
const memberOptions = [
  { label: '产品', value: 'pm' },
  { label: '设计', value: 'design' },
  { label: '前端', value: 'frontend' },
];
const handleSubmit = ({ values, errors }) => {
  console.log(values, errors);
};
</script>

按需导入

ts
import { Form, FormItem } from 'x-next';

Form Props

参数说明类型默认值
model表单数据对象Record<string, any>必填
layout表单布局'horizontal' | 'vertical' | 'inline''horizontal'
size表单控件尺寸'mini' | 'small' | 'medium' | 'large'跟随全局配置
labelColProps标签栅格配置object{ span: 5, offset: 0 }
wrapperColProps控件栅格配置object{ span: 19, offset: 0 }
labelColStyle标签列样式object-
wrapperColStyle控件列样式object-
labelAlign标签对齐方式'left' | 'right''right'
disabled是否禁用整个表单booleanundefined
rules表单校验规则Record<string, FieldRule | FieldRule[]>-
autoLabelWidth自动计算标签宽度,仅水平布局生效booleanfalse
id表单 id 属性和表单控件 id 前缀string-
scrollToFirstError校验失败后滚动到第一个错误字段,可传滚动配置boolean | ScrollIntoViewOptionsfalse

Form Events

事件名说明回调参数
submit表单提交时触发{ values, errors }, event
submit-success校验成功时触发values, event
submit-failed校验失败时触发{ values, errors }, event

Form Methods

方法说明参数
validate校验全部表单数据(callback?)
validateField校验指定字段(field, callback?)
resetFields重置字段值和校验状态(field?)
clearValidate清除字段校验状态(field?)
setFields设置表单项值与状态(data)
scrollToField滚动到指定字段(field, options?)

FormItem Props

参数说明类型默认值
field字段路径string''
label标签文本string-
tooltip标签提示string-
showColon是否显示冒号booleanfalse
noStyle是否去除布局样式booleanfalse
disabled是否禁用当前项booleanundefined
help帮助文案string-
extra额外文案string-
required是否必填booleanfalse
asteriskPosition星号位置'start' | 'end''start'
rules当前项校验规则FieldRule | FieldRule[]-
validateStatus手动指定校验状态'success' | 'warning' | 'error' | 'validating'-
validateTrigger触发校验的事件'change' | 'input' | 'focus' | 'blur' | string[]'change'
labelColProps当前项标签列配置object继承 Form
wrapperColProps当前项控件列配置object继承 Form
hideLabel是否隐藏标签booleanfalse
hideAsterisk是否隐藏星号booleanfalse
labelColStyle标签列样式object继承 Form
wrapperColStyle控件列样式object继承 Form
rowProps当前项 Row 配置object-
rowClass当前项 Row classstring | array | object-
contentClass控件包裹层 classstring | array | object-
contentFlex内容层是否启用 flexbooleantrue
mergeProps已废弃的子元素 props 合并控制boolean | functiontrue
labelColFlex标签列 flex 宽度number | string-
feedback是否显示反馈图标booleanfalse
labelComponent标签渲染元素string'label'
labelAttrs标签元素属性object-

FormItem Slots

插槽名说明
default表单控件内容
label自定义标签
help自定义帮助信息
extra自定义额外内容