Element Plus 表单由以下几个关键部分构成:
<el-form>
: 表单容器。它是整个表单的根组件,负责管理表单数据、校验规则、布局方式等。<el-form-item>
: 表单项容器。用于包裹一个具体的表单控件(如输入框、选择器等)及其标签(label)、校验状态提示。它是实现布局和校验的基本单元。- 表单控件 (Form Controls): 实际的输入组件,如
<el-input>
,<el-select>
,<el-date-picker>
,<el-checkbox>
,<el-switch>
等。这些控件通过v-model
或:model
与el-form
的数据模型绑定。 - 数据模型 (Model): 一个 JavaScript 对象,通常在
setup
或data
中定义,用于存储表单各字段的值。el-form
的model
属性指向这个对象。 - 校验规则 (Rules): 一个对象,定义了每个表单字段需要满足的校验条件(如必填、格式、长度等)。
el-form
的rules
属性指向这个对象。
<el-form>
详解
- 作用: 表单的顶层容器,协调
el-form-item
和表单控件。 - 核心属性:
model
: 必需。绑定表单的数据对象。例如:model="form"
, 其中form
是{ name: '', email: '' }
这样的对象。rules
: 可选。定义表单校验规则的对象。例如:rules="formRules"
。label-width
: 设置所有el-form-item
标签(label)的宽度。可以是字符串如"100px"
或数字100
。如果某个el-form-item
需要不同的宽度,可以在该el-form-item
上单独设置。label-position
: 设置标签的位置。可选值:right
(默认): 标签在控件右侧(当label-width
有效时,通常表现为左对齐标签,右对齐控件)。left
: 标签在控件左侧。top
: 标签在控件上方。常用于移动端或需要节省水平空间的场景。
label-suffix
: 标签后缀,如冒号":"
(默认) 或其他字符。hide-required-asterisk
: 是否隐藏必填字段的红色星号标记。默认false
(显示星号)。require-asterisk-position
: 星号位置。left
(默认) 或right
。inline
: 是否让表单项 (el-form-item
) 水平排列。设置为true
时,表单项会显示在同一行,适合构建查询表单。此时label-position
通常为right
或left
。disabled
: 是否禁用该表单内所有控件。如果控件自身也有disabled
,则以控件自身的设置为准。status-icon
: 是否在输入框中显示校验状态图标(如成功对勾、错误叉号)。默认false
。validate-on-rule-change
: 当rules
属性改变后,是否立即触发一次校验。默认true
。scroll-to-error
: 提交表单时,如果校验失败,是否自动滚动到第一个错误的表单项。默认false
。size
: 为表单内的控件设置统一的尺寸 (large
,default
,small
)。可以被控件自身的size
覆盖。
- 核心方法 (通过 ref 调用):
validate(callback: Function)
: 对整个表单进行校验。callback
函数接收两个参数:valid
(布尔值,表示校验是否通过) 和invalidFields
(包含未通过校验字段的对象)。这是提交表单前必须调用的方法。validateField(props: string | string[], callback: Function)
: 对表单的指定字段进行校验。props
可以是字段名字符串或字符串数组。resetFields()
: 对整个表单进行重置,将其恢复到初始状态(清空输入、移除校验状态)。注意:这会将model
的值重置为el-form
组件初始化时model
对象的值。如果初始值是''
,则重置为空;如果初始值是'default'
,则重置为'default'
。clearValidate(props?: string | string[])
: 移除表单项的校验结果。可以指定一个或多个字段名,或不传参清除所有。scrollToField(prop: string)
: 滚动到指定prop
名称的表单项。
<el-form-item>
详解
- 作用: 包裹一个表单控件,提供布局、标签、校验状态显示(错误信息、加载状态图标)。
- 核心属性:
prop
: 必需(当el-form
有rules
时)。指定该表单项对应model
中的字段名。例如prop="name"
对应model.name
。这是el-form
能够找到并校验特定字段的关键。label
: 该表单项的标签文本。label-width
: 覆盖el-form
的label-width
,设置此单项的标签宽度。required
: 是否必填。如果rules
中有required: true
,通常会自动显示红色星号,此属性可显式控制。rules
: 为该单项设置独立的校验规则。如果el-form
的rules
中也定义了此prop
的规则,两者会合并。error
: 自定义显示的错误信息文本。设置后,会强制显示为错误状态,优先级高于校验规则产生的错误信息。常用于服务端返回的错误。show-message
: 是否显示校验错误信息。默认true
。inline-message
: 是否以行内形式显示校验信息(错误信息显示在控件右侧,而不是下方)。默认false
。size
: 设置该单项内控件的尺寸。
- 插槽 (Slots):
- 默认插槽: 放置表单控件。
label
: 自定义标签内容(可以包含 HTML 或组件)。error
: 自定义错误信息的显示内容。
表单校验 (Validation) 详解
校验是 el-form
最强大的功能之一。它支持声明式规则和灵活的异步校验。
校验规则 (
rules
) 结构:rules
是一个对象,其键 (key
) 对应model
中的字段名 (prop
)。- 值是一个数组,包含一个或多个校验规则对象。
- 规则对象常用属性:
required
:true
表示必填。message
: 校验失败时显示的提示消息。trigger
: 触发校验的事件。常用值:blur
: 失去焦点时触发。change
: 值改变时触发(对于input
是输入时,对于select
是选择时)。- 可以是数组
['blur', 'change']
。
type
: 数据类型。如string
,number
,boolean
,array
,object
,date
,url
,email
等。指定类型后,校验器会进行相应的类型检查。min
/max
: 字符串长度或数组长度的最小/最大值。len
: 长度必须等于指定值。pattern
: 正则表达式,值必须匹配该模式。validator
: 自定义校验函数。接收三个参数:rule
(当前规则对象),value
(当前字段的值),callback
(校验完成后的回调函数)。必须调用callback()
,传入new Error('错误信息')
表示失败,或callback()
(无参数) 表示成功。asyncValidator
: 异步自定义校验函数。与validator
类似,但它返回一个Promise
。Promise
resolve 表示成功,reject 一个Error
实例表示失败。
内置校验类型:
- Element Plus 内置了对
string
,number
,boolean
,array
,object
,date
,url
,email
,pattern
等类型的校验。 - 例如,
type: 'email'
会自动使用邮箱正则进行校验。
- Element Plus 内置了对
自定义校验函数示例:
const formRules = reactive({password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 6, message: '密码长度至少6位', trigger: 'blur' }],confirmPassword: [{ required: true, message: '请确认密码', trigger: 'blur' },{validator: (rule, value, callback) => {if (value === '') {callback(new Error('请再次输入密码'));} else if (value !== form.password) { // 假设 form 是 model 对象callback(new Error('两次输入的密码不一致'));} else {callback(); // 校验通过}},trigger: 'blur'}],asyncCheck: [{asyncValidator: (rule, value, callback) => {return new Promise((resolve, reject) => {// 模拟异步请求setTimeout(() => {if (value === 'async') {resolve(); // 成功} else {reject(new Error('必须输入 "async"')); // 失败}}, 1000);});},trigger: 'blur'}] });