基础表单
<template>
<el-form
ref="ruleFormRef"
:model="form"
:rules="rules"
label-width="100px"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="爱好">
<!-- 注意: 爱好没有 prop, 所以不会参与 el-form 的校验 -->
<el-checkbox-group v-model="form.hobby">
<el-checkbox label="读书" />
<el-checkbox label="音乐" />
<el-checkbox label="电影" />
</el-checkbox-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">提交</el-button>
<el-button @click="resetForm(ruleFormRef)">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
const ruleFormRef = ref() // 用于获取 el-form 实例
// 表单数据
const form = reactive({
username: '',
email: '',
hobby: [] // 数组
})
// 校验规则
const rules = reactive({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 15, message: '长度在 3 到 15 个字符', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
]
})
// 提交表单
const submitForm = async (formEl) => {
if (!formEl) return;
try {
// validate 返回 Promise
await formEl.validate()
ElMessage.success('提交成功!')
console.log('表单数据:', form)
} catch (error) {
ElMessage.error('校验失败!')
console.log('校验失败:', error)
}
}
// 重置表单
const resetForm = (formEl) => {
if (!formEl) return;
formEl.resetFields()
}
</script>
行内表单 (Inline Form)
<template>
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="用户名">
<el-input v-model="searchForm.username" placeholder="用户名" />
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchForm.status" placeholder="选择状态">
<el-option label="全部" value="" />
<el-option label="启用" value="1" />
<el-option label="禁用" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive } from 'vue'
const searchForm = reactive({
username: '',
status: ''
})
const onSubmit = () => {
console.log('查询条件:', searchForm)
}
</script>
标签在上方的表单
<template>
<el-form
:model="form"
:rules="rules"
label-position="top"
label-width="100px"
>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" />
</el-form-item>
<el-form-item label="项目描述" prop="description">
<el-input v-model="form.description" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary">保存</el-button>
</el-form-item>
</el-form>
</template>
动态增减表单项
<template>
<el-form :model="dynamicForm" ref="dynamicFormRef">
<el-form-item
v-for="(domain, index) in dynamicForm.domains"
:key="domain.key"
:label="index === 0 ? '域名' : ''" <!-- 只为第一个显示标签 -->
:prop="'domains.' + index + '.value'"
:rules="{
required: true, message: '域名不能为空', trigger: 'blur'
}"
>
<el-input v-model="domain.value" style="width: 300px; margin-right: 10px;" />
<el-button @click.prevent="removeDomain(domain)">删除</el-button>
</el-form-item>
<el-form-item>
<el-button @click="addDomain">新增域名</el-button>
<el-button type="primary" @click="submitDynamicForm(dynamicFormRef)">提交</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, reactive } from 'vue'
const dynamicFormRef = ref()
const dynamicForm = reactive({
domains: [
{ value: '', key: Date.now() } // key 用于 v-for 的唯一性
]
})
const addDomain = () => {
dynamicForm.domains.push({
value: '',
key: Date.now() + Math.random()
})
}
const removeDomain = (item) => {
const index = dynamicForm.domains.indexOf(item)
if (index !== -1) {
dynamicForm.domains.splice(index, 1)
}
}
const submitDynamicForm = async (formEl) => {
if (!formEl) return;
try {
await formEl.validate()
ElMessage.success('提交成功!')
console.log('动态表单数据:', dynamicForm.domains)
} catch (error) {
ElMessage.error('校验失败!')
}
}
</script>
使用建议与最佳实践
ref
是关键: 务必给el-form
添加ref
,以便调用validate
,resetFields
等方法。prop
必须匹配model
:el-form-item
的prop
值必须是model
对象中存在的属性名,且路径要正确(如嵌套对象用user.name
)。- 合理使用
trigger
:blur
适合必填和格式校验,避免用户输入时频繁报错。change
适合实时性要求高的校验(如密码强度)。 resetFields
的陷阱: 它重置的是组件初始化时的model
值。如果需要重置到一个特定的值(比如空对象{}
),可以在调用resetFields()
后手动设置model
,或者使用clearValidate()
和手动清空数据。- 异步校验: 使用
asyncValidator
处理需要请求后端验证的场景(如用户名唯一性检查)。注意防抖。 status-icon
: 开启后,用户能更直观地看到输入状态。scroll-to-error
: 对于长表单,开启此功能能提升用户体验。inline-message
: 在空间紧凑的布局中,使用行内错误信息可以节省垂直空间。- 自定义错误信息: 使用
el-form-item
的error
属性或slots
可以完全控制错误信息的显示。 - 组合使用:
el-form
可以与el-row
/el-col
结合,实现更复杂的响应式表单布局。
掌握 el-form
的数据绑定、校验机制和布局控制,是高效开发 Vue + Element Plus 应用的基础。它极大地简化了表单处理的复杂性。