Form 表单
高性能表单控件,自带数据域管理。包含数据录入、校验以及对应样式。 集成 @ant-design-vue/use 更加灵活的使用表单组件。
何时使用
- 用于创建一个实体或收集信息。
- 需要对输入的数据类型进行校验时。
表单
我们为 form
提供了以下三种排列方式:
- 水平排列:标签和表单控件水平排列;(默认)
- 垂直排列:标签和表单控件上下垂直排列;
- 行内排列:表单项水平行内排列。
表单域
表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。
代码演示
Activity name
Activity zone
please select your zone
Activity time
Instant delivery
Activity type
OnlinePromotionOffline
Resources
SponsorVenue
Activity form
CreateCancel
基本的表单数据域控制展示,包含布局、初始化、验证、提交。
<template>
<a-form :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="Activity name">
<a-input v-model:value="formState.name" />
</a-form-item>
<a-form-item label="Activity zone">
<a-select v-model:value="formState.region" placeholder="please select your zone">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Activity time">
<a-date-picker
v-model:value="formState.date1"
show-time
type="date"
placeholder="Pick a date"
style="width: 100%"
/>
</a-form-item>
<a-form-item label="Instant delivery">
<a-switch v-model:checked="formState.delivery" />
</a-form-item>
<a-form-item label="Activity type">
<a-checkbox-group v-model:value="formState.type">
<a-checkbox value="1" name="type">Online</a-checkbox>
<a-checkbox value="2" name="type">Promotion</a-checkbox>
<a-checkbox value="3" name="type">Offline</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item label="Resources">
<a-radio-group v-model:value="formState.resource">
<a-radio value="1">Sponsor</a-radio>
<a-radio value="2">Venue</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="Activity form">
<a-input v-model:value="formState.desc" type="textarea" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">Create</a-button>
<a-button style="margin-left: 10px">Cancel</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { Moment } from 'moment';
import { defineComponent, reactive, toRaw, UnwrapRef } from 'vue';
interface FormState {
name: string;
region: string | undefined;
date1: Moment | undefined;
delivery: boolean;
type: string[];
resource: string;
desc: string;
}
export default defineComponent({
setup() {
const formState: UnwrapRef<FormState> = reactive({
name: '',
region: undefined,
date1: undefined,
delivery: false,
type: [],
resource: '',
desc: '',
});
const onSubmit = () => {
console.log('submit!', toRaw(formState));
};
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
formState,
onSubmit,
};
},
});
</script>
Log in
水平登录栏,常用在顶部导航栏中。
<template>
<a-form
layout="inline"
:model="formState"
@finish="handleFinish"
@finishFailed="handleFinishFailed"
>
<a-form-item>
<a-input v-model:value="formState.user" placeholder="Username">
<template #prefix><UserOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
</a-input>
</a-form-item>
<a-form-item>
<a-input v-model:value="formState.password" type="password" placeholder="Password">
<template #prefix><LockOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
</a-input>
</a-form-item>
<a-form-item>
<a-button
type="primary"
html-type="submit"
:disabled="formState.user === '' || formState.password === ''"
>
Log in
</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { defineComponent, reactive, UnwrapRef } from 'vue';
interface FormState {
user: string;
password: string;
}
export default defineComponent({
setup() {
const formState: UnwrapRef<FormState> = reactive({
user: '',
password: '',
});
const handleFinish = (values: FormState) => {
console.log(values, formState);
};
const handleFinishFailed = (errors: ValidateErrorEntity<FormState>) => {
console.log(errors);
};
return {
formState,
handleFinish,
handleFinishFailed,
};
},
components: {
UserOutlined,
LockOutlined,
},
});
</script>
Form Layout
HorizontalVerticalInline
Field A
Field B
Submit
表单有三种布局。
<template>
<a-form :layout="formState.layout" :model="formState" v-bind="formItemLayout">
<a-form-item label="Form Layout">
<a-radio-group v-model:value="formState.layout">
<a-radio-button value="horizontal">Horizontal</a-radio-button>
<a-radio-button value="vertical">Vertical</a-radio-button>
<a-radio-button value="inline">Inline</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="Field A">
<a-input v-model:value="formState.fieldA" placeholder="input placeholder" />
</a-form-item>
<a-form-item label="Field B">
<a-input v-model:value="formState.fieldB" placeholder="input placeholder" />
</a-form-item>
<a-form-item :wrapper-col="buttonItemLayout.wrapperCol">
<a-button type="primary">Submit</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { computed, defineComponent, reactive, UnwrapRef } from 'vue';
interface FormState {
layout: 'horizontal' | 'vertical' | 'inline';
fieldA: string;
fieldB: string;
}
export default defineComponent({
setup() {
const formState: UnwrapRef<FormState> = reactive({
layout: 'horizontal',
fieldA: '',
fieldB: '',
});
const formItemLayout = computed(() => {
const { layout } = formState;
return layout === 'horizontal'
? {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
}
: {};
});
const buttonItemLayout = computed(() => {
const { layout } = formState;
return layout === 'horizontal'
? {
wrapperCol: { span: 14, offset: 4 },
}
: {};
});
return {
formState,
formItemLayout,
buttonItemLayout,
};
},
});
</script>
Activity name
Activity zone
please select your zone
Activity time
Instant delivery
Activity type
OnlinePromotionOffline
Resources
SponsorVenue
Activity form
CreateReset
Form 组件提供了表单验证的功能,只需要通过 rules
属性传入约定的验证规则,并将 FormItem
的 prop
属性设置为需校验的字段名即可。校验规则参见 async-validator
<template>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item ref="name" label="Activity name" name="name">
<a-input v-model:value="formState.name" />
</a-form-item>
<a-form-item label="Activity zone" name="region">
<a-select v-model:value="formState.region" placeholder="please select your zone">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Activity time" required name="date1">
<a-date-picker
v-model:value="formState.date1"
show-time
type="date"
placeholder="Pick a date"
style="width: 100%"
/>
</a-form-item>
<a-form-item label="Instant delivery" name="delivery">
<a-switch v-model:checked="formState.delivery" />
</a-form-item>
<a-form-item label="Activity type" name="type">
<a-checkbox-group v-model:value="formState.type">
<a-checkbox value="1" name="type">Online</a-checkbox>
<a-checkbox value="2" name="type">Promotion</a-checkbox>
<a-checkbox value="3" name="type">Offline</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item label="Resources" name="resource">
<a-radio-group v-model:value="formState.resource">
<a-radio value="1">Sponsor</a-radio>
<a-radio value="2">Venue</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="Activity form" name="desc">
<a-textarea v-model:value="formState.desc" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">Create</a-button>
<a-button style="margin-left: 10px" @click="resetForm">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { Moment } from 'moment';
import { defineComponent, reactive, ref, toRaw, UnwrapRef } from 'vue';
interface FormState {
name: string;
region: string | undefined;
date1: Moment | undefined;
delivery: boolean;
type: string[];
resource: string;
desc: string;
}
export default defineComponent({
setup() {
const formRef = ref();
const formState: UnwrapRef<FormState> = reactive({
name: '',
region: undefined,
date1: undefined,
delivery: false,
type: [],
resource: '',
desc: '',
});
const rules = {
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
],
region: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
date1: [{ required: true, message: 'Please pick a date', trigger: 'change', type: 'object' }],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change',
},
],
resource: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
};
const onSubmit = () => {
formRef.value
.validate()
.then(() => {
console.log('values', formState, toRaw(formState));
})
.catch((error: ValidateErrorEntity<FormState>) => {
console.log('error', error);
});
};
const resetForm = () => {
formRef.value.ruleformState.resetFields();
};
return {
formRef,
labelCol: { span: 4 },
wrapperCol: { span: 14 },
other: '',
formState,
rules,
onSubmit,
resetForm,
};
},
});
</script>
Password
Confirm
Age
SubmitReset
这个例子中展示了如何使用自定义验证规则来完成密码的二次验证。本例还使用 has-feedback
属性为输入框添加了表示校验结果的反馈图标。 更多高级用法可参考 async-validator
<template>
<a-form
name="custom-validation"
ref="formRef"
:model="formState"
:rules="rules"
v-bind="layout"
@finish="handleFinish"
@finishFailed="handleFinishFailed"
>
<a-form-item required has-feedback label="Password" name="pass">
<a-input v-model:value="formState.pass" type="password" autocomplete="off" />
</a-form-item>
<a-form-item has-feedback label="Confirm" name="checkPass">
<a-input v-model:value="formState.checkPass" type="password" autocomplete="off" />
</a-form-item>
<a-form-item has-feedback label="Age" name="age">
<a-input-number v-model:value="formState.age" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" html-type="submit">Submit</a-button>
<a-button style="margin-left: 10px" @click="resetForm">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { RuleObject, ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { defineComponent, reactive, ref, UnwrapRef } from 'vue';
interface FormState {
pass: string;
checkPass: string;
age: number | undefined;
}
export default defineComponent({
setup() {
const formRef = ref();
const formState: UnwrapRef<FormState> = reactive({
pass: '',
checkPass: '',
age: undefined,
});
let checkAge = async (rule: RuleObject, value: number) => {
if (!value) {
return Promise.reject('Please input the age');
}
if (!Number.isInteger(value)) {
return Promise.reject('Please input digits');
} else {
if (value < 18) {
return Promise.reject('Age must be greater than 18');
} else {
return Promise.resolve();
}
}
};
let validatePass = async (rule: RuleObject, value: string) => {
if (value === '') {
return Promise.reject('Please input the password');
} else {
if (formState.checkPass !== '') {
formRef.value.validateField('checkPass');
}
return Promise.resolve();
}
};
let validatePass2 = async (rule: RuleObject, value: string) => {
if (value === '') {
return Promise.reject('Please input the password again');
} else if (value !== formState.pass) {
return Promise.reject("Two inputs don't match!");
} else {
return Promise.resolve();
}
};
const rules = {
pass: [{ validator: validatePass, trigger: 'change' }],
checkPass: [{ validator: validatePass2, trigger: 'change' }],
age: [{ validator: checkAge, trigger: 'change' }],
};
const layout = {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
};
const handleFinish = (values: FormState) => {
console.log(values, formState);
};
const handleFinishFailed = (errors: ValidateErrorEntity<FormState>) => {
console.log(errors);
};
const resetForm = () => {
formRef.value.resetFields();
};
return {
formState,
formRef,
rules,
layout,
handleFinishFailed,
handleFinish,
resetForm,
};
},
});
</script>
Add field
SubmitReset
动态增加、减少表单项。
<template>
<a-form ref="formRef" :model="dynamicValidateForm" v-bind="formItemLayoutWithOutLabel">
<a-form-item
v-for="(domain, index) in dynamicValidateForm.domains"
:key="domain.key"
v-bind="index === 0 ? formItemLayout : {}"
:label="index === 0 ? 'Domains' : ''"
:name="['domains', index, 'value']"
:rules="{
required: true,
message: 'domain can not be null',
trigger: 'change',
}"
>
<a-input
v-model:value="domain.value"
placeholder="please input domain"
style="width: 60%; margin-right: 8px"
/>
<MinusCircleOutlined
v-if="dynamicValidateForm.domains.length > 1"
class="dynamic-delete-button"
:disabled="dynamicValidateForm.domains.length === 1"
@click="removeDomain(domain)"
/>
</a-form-item>
<a-form-item v-bind="formItemLayoutWithOutLabel">
<a-button type="dashed" style="width: 60%" @click="addDomain">
<PlusOutlined />
Add field
</a-button>
</a-form-item>
<a-form-item v-bind="formItemLayoutWithOutLabel">
<a-button type="primary" html-type="submit" @click="submitForm">Submit</a-button>
<a-button style="margin-left: 10px" @click="resetForm">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { defineComponent, reactive, ref, UnwrapRef } from 'vue';
interface Domain {
value: string;
key: number;
}
export default defineComponent({
setup() {
const formRef = ref();
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 20 },
},
};
const formItemLayoutWithOutLabel = {
wrapperCol: {
xs: { span: 24, offset: 0 },
sm: { span: 20, offset: 4 },
},
};
const dynamicValidateForm: UnwrapRef<{ domains: Domain[] }> = reactive({
domains: [],
});
const submitForm = () => {
formRef.value
.validate()
.then(() => {
console.log('values', dynamicValidateForm.domains);
})
.catch((error: ValidateErrorEntity<any>) => {
console.log('error', error);
});
};
const resetForm = () => {
formRef.value.resetFields();
};
const removeDomain = (item: Domain) => {
let index = dynamicValidateForm.domains.indexOf(item);
if (index !== -1) {
dynamicValidateForm.domains.splice(index, 1);
}
};
const addDomain = () => {
dynamicValidateForm.domains.push({
value: '',
key: Date.now(),
});
};
return {
formRef,
formItemLayout,
formItemLayoutWithOutLabel,
dynamicValidateForm,
submitForm,
resetForm,
removeDomain,
addDomain,
};
},
components: {
MinusCircleOutlined,
PlusOutlined,
},
});
</script>
<style>
.dynamic-delete-button {
cursor: pointer;
position: relative;
top: 4px;
font-size: 24px;
color: #999;
transition: all 0.3s;
}
.dynamic-delete-button:hover {
color: #777;
}
.dynamic-delete-button[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
</style>
Activity name
Activity zone
please select your zone
Activity type
OnlinePromotionOffline
CreateReset
集成 @ant-design-vue/use 更加灵活的使用表单组件。useForm
提供表单校验逻辑和状态。
<template>
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="Activity name" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" />
</a-form-item>
<a-form-item label="Activity zone" v-bind="validateInfos.region">
<a-select v-model:value="modelRef.region" placeholder="please select your zone">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Activity type" v-bind="validateInfos.type">
<a-checkbox-group v-model:value="modelRef.type">
<a-checkbox value="1" name="type">Online</a-checkbox>
<a-checkbox value="2" name="type">Promotion</a-checkbox>
<a-checkbox value="3" name="type">Offline</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="onSubmit">Create</a-button>
<a-button style="margin-left: 10px" @click="resetFields">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { defineComponent, reactive, toRaw } from 'vue';
import { useForm } from '@ant-design-vue/use';
export default defineComponent({
setup() {
const modelRef = reactive({
name: '',
region: undefined,
type: [],
});
const rulesRef = reactive({
name: [
{
required: true,
message: 'Please input name',
},
],
region: [
{
required: true,
message: 'Please select region',
},
],
type: [
{
required: true,
message: 'Please select type',
type: 'array',
},
],
});
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef);
const onSubmit = () => {
validate()
.then(() => {
console.log(toRaw(modelRef));
})
.catch(err => {
console.log('error', err);
});
};
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
validateInfos,
resetFields,
modelRef,
onSubmit,
};
},
});
</script>
Activity name
Sub name
CreateReset
集成 @ant-design-vue/use 更加灵活的使用表单组件。使用点字符串拼接进行嵌套数据校验。
<template>
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="Activity name" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" />
</a-form-item>
<a-form-item label="Sub name" v-bind="validateInfos['sub.name']">
<a-input v-model:value="modelRef.sub.name" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="onSubmit">Create</a-button>
<a-button style="margin-left: 10px" @click="reset">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { defineComponent, reactive, toRaw } from 'vue';
import { useForm } from '@ant-design-vue/use';
export default defineComponent({
setup() {
const modelRef = reactive({
name: '',
sub: {
name: '',
},
});
const { resetFields, validate, validateInfos } = useForm(
modelRef,
reactive({
name: [
{
required: true,
message: 'Please input name',
},
],
'sub.name': [
{
required: true,
message: 'Please input sub name',
},
],
}),
);
const onSubmit = () => {
validate()
.then(res => {
console.log(res, toRaw(modelRef));
})
.catch(err => {
console.log('error', err);
});
};
const reset = () => {
resetFields();
};
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
validateInfos,
reset,
modelRef,
onSubmit,
};
},
});
</script>
Activity name
Activity zone
please select your zone
CreateReset
集成 @ant-design-vue/use 更加灵活的使用表单组件。useForm
自定义触发校验时机
<template>
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="Activity name" v-bind="validateInfos.name">
<a-input
v-model:value="modelRef.name"
@blur="validate('name', { trigger: 'blur' }).catch(() => {})"
/>
</a-form-item>
<a-form-item label="Activity zone" v-bind="validateInfos.region">
<a-select v-model:value="modelRef.region" placeholder="please select your zone">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="onSubmit">Create</a-button>
<a-button style="margin-left: 10px" @click="resetFields">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { defineComponent, reactive, toRaw } from 'vue';
import { useForm } from '@ant-design-vue/use';
export default defineComponent({
setup() {
const modelRef = reactive({
name: '',
region: undefined,
});
const rulesRef = reactive({
name: [
{
required: true,
message: 'Please input Activity name',
},
{
min: 3,
max: 5,
message: 'Length should be 3 to 5',
trigger: 'blur',
},
],
region: [
{
required: true,
message: 'Please select region',
},
],
});
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef);
const onSubmit = () => {
validate()
.then(() => {
console.log(toRaw(modelRef));
})
.catch(err => {
console.log('error', err);
});
};
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
validate,
validateInfos,
resetFields,
modelRef,
onSubmit,
};
},
});
</script>
Activity name
Activity zone
please select your zone
Activity type
OnlinePromotionOffline
CreateReset
集成 @ant-design-vue/use 更加灵活的使用表单组件。useForm
合并展示表单校验信息。
<template>
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="Activity name" required>
<a-input v-model:value="modelRef.name" />
</a-form-item>
<a-form-item label="Activity zone" required>
<a-select v-model:value="modelRef.region" placeholder="please select your zone">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="Activity type" required>
<a-checkbox-group v-model:value="modelRef.type">
<a-checkbox value="1" name="type">Online</a-checkbox>
<a-checkbox value="2" name="type">Promotion</a-checkbox>
<a-checkbox value="3" name="type">Offline</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item class="error-infos" :wrapper-col="{ span: 14, offset: 4 }" v-bind="errorInfos">
<a-button type="primary" @click.prevent="onSubmit">Create</a-button>
<a-button style="margin-left: 10px" @click="resetFields">Reset</a-button>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { reactive, toRaw, computed, defineComponent } from 'vue';
import { useForm } from '@ant-design-vue/use';
import { toArray } from 'lodash-es';
export default defineComponent({
setup() {
const modelRef = reactive({
name: '',
region: undefined,
type: [],
});
const rulesRef = reactive({
name: [
{
required: true,
message: 'Please input name',
},
],
region: [
{
required: true,
message: 'Please select region',
},
],
type: [
{
required: true,
message: 'Please select type',
type: 'array',
},
],
});
const { resetFields, validate, validateInfos, mergeValidateInfo } = useForm(modelRef, rulesRef);
const onSubmit = () => {
validate()
.then(() => {
console.log(toRaw(modelRef));
})
.catch(err => {
console.log('error', err);
});
};
const errorInfos = computed(() => {
return mergeValidateInfo(toArray(validateInfos));
});
return {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
validateInfos,
resetFields,
modelRef,
onSubmit,
errorInfos,
};
},
});
</script>
<style scoped>
.error-infos :deep(.ant-form-explain) {
white-space: pre-line;
}
</style>
API
Form
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
model | 表单数据对象 | object | ||
rules | 表单验证规则 | object | ||
hideRequiredMark | 隐藏所有表单项的必选标记 | Boolean | false | |
labelAlign | label 标签的文本对齐方式 | ‘left’ | ‘right’ | ‘right’ | |
layout | 表单布局 | ‘horizontal’|’vertical’|’inline’ | ‘horizontal’ | |
labelCol | label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} | object | ||
wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | object | ||
colon | 配置 Form.Item 的 colon 的默认值 (只有在属性 layout 为 horizontal 时有效) | boolean | true | |
validateOnRuleChange | 是否在 rules 属性改变后立即触发一次验证 | boolean | true | |
scrollToFirstError | 提交失败自动滚动到第一个错误字段 | boolean | false | 2.0.0 |
name | 表单名称,会作为表单字段 id 前缀使用 | string | - | 2.0.0 |
validateTrigger | 统一设置字段校验规则 | string | string[] | change | 2.0.0 |
事件
事件名称 | 说明 | 回调参数 | 版本 |
---|---|---|---|
submit | 数据验证成功后回调事件 | Function(e:Event) | | |
validate | 任一表单项被校验后触发 | 被校验的表单项 name 值,校验是否通过,错误消息(如果存在) | |
finish | 提交表单且数据验证成功后回调事件 | function(values) | - |
finishFailed | 提交表单且数据验证失败后回调事件 | function({ values, errorFields, outOfDate }) | - |
方法
方法名 | 说明 | 参数 |
---|---|---|
validate | 触发表单验证, 同 validateFields | (nameList?: NamePath[]) => Promise |
validateFields | 触发表单验证 | (nameList?: NamePath[]) => Promise |
scrollToField | 滚动到对应字段位置 | (name: NamePath, options: [ScrollOptions]) => void |
resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | — |
clearValidate | 移除表单项的校验结果。传入待移除的表单项的 name 属性或者 name 组成的数组,如不传则移除整个表单的校验结果 | Function(name: array | string) |
Form.Item
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
name | 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 | string | ||
rules | 表单验证规则 | object | array | ||
autoLink | 是否自动关联表单域,对于大部分情况都可以使用自动关联,如果不满足自动关联的条件,可以手动关联,参见下方注意事项 | boolean | true | |
colon | 配合 label 属性使用,表示是否显示 label 后面的冒号 | boolean | true | |
extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 | string|slot | ||
hasFeedback | 配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用 | boolean | false | |
help | 提示信息,如不设置,则会根据校验规则自动生成 | string|slot | ||
htmlFor | 设置子元素 label htmlFor 属性 | string | ||
label | label 标签的文本 | string|slot | ||
labelCol | label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} | object | ||
labelAlign | 标签文本对齐方式 | ‘left’ | ‘right’ | ‘right’ | |
required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | false | |
validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:’success’ ‘warning’ ‘error’ ‘validating’ | string | ||
wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | object | ||
validateFirst | 当某一规则校验不通过时,是否停止剩下的规则的校验。 | boolean | false | 2.0.0 |
validateTrigger | 设置字段校验的时机 | string | string[] | change | 2.0.0 |
注意:
Form.Item 会对唯一子元素进行劫持,并监听 blur
和 change
事件,来达到自动校验的目的,所以请确保表单域没有其它元素包裹。如果有多个子元素,将只会监听第一个子元素的变化。
如果要监听的表单域不满足自动监听的条件,可以通过如下方式关联表单域:
<a-form-item name="form.name" ref="name" :autoLink="false">
<a-input v-model:value="other" />
<span>hahha</span>
<div>
<a-input
v-model:value="form.name"
@blur="() => {$refs.name.onFieldBlur()}"
@change="() => {$refs.name.onFieldChange()}"
/>
</div>
</a-form-item>
校验规则
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
trigger | 校验触发的时机 | ‘blur’ | ‘change’ | [‘change’, ‘blur’] | - |
enum | 枚举类型 | string | - |
len | 字段长度 | number | - |
max | 最大长度 | number | - |
message | 校验文案 | string | - |
min | 最小长度 | number | - |
pattern | 正则表达式校验 | RegExp | - |
required | 是否必选 | boolean | false |
transform | 校验前转换字段值 | function(value) => transformedValue:any | - |
type | 内建校验类型,可选项 | string | ‘string’ |
validator | 自定义校验(注意,callback 必须被调用) | function(rule, value, callback) | - |
whitespace | 必选时,空格是否会被视为错误 | boolean | false |
更多高级用法可研究 async-validator。