Form 表单 
概述 
表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。使用表单,您可以收集、验证和提交数据。
提示
Form 组件已经从 2.x 的 Float 布局升级为 Flex 布局。
学习目标 
- 掌握 el-form 基础结构
- 理解 el-form-item 表单项的使用
- 学会表单数据绑定(v-model)
- 掌握表单布局:inline、label-position
- 了解表单尺寸控制
- 学会表单禁用状态
- 掌握表单重置和提交
- 理解表单验证机制
基础用法 
典型表单 
最基础的表单包括各种输入表单项,比如input、select、radio、checkbox等。在每一个 form 组件中,你需要一个 form-item 字段作为输入项的容器,用于获取值与验证值。
<template>
  <el-form :model="form" label-width="120px">
    <el-form-item label="用户名">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="密码">
      <el-input v-model="form.password" type="password" />
    </el-form-item>
    <el-form-item label="邮箱">
      <el-input v-model="form.email" />
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onSubmit">提交</el-button>
      <el-button @click="onReset">重置</el-button>
    </el-form-item>
  </el-form>
</template>
<script setup>
import { reactive } from 'vue'
const form = reactive({
  name: '',
  password: '',
  email: ''
})
const onSubmit = () => {
  console.log('提交表单:', form)
}
const onReset = () => {
  form.name = ''
  form.password = ''
  form.email = ''
}
</script>W3C 标准
当一个表单中只有一个单行文本输入字段时,浏览器应当将在此字段中按下 Enter(回车键)的行为视为提交表单的请求。如果希望阻止这一默认行为,可以在 <el-form> 标签上添加 @submit.prevent。
行内表单 
当垂直方向空间受限且表单较简单时,可以在一行内放置表单。通过设置 inline 属性为 true 可以让表单域变为行内的表单域。
<template>
  <el-form :inline="true" :model="formInline" class="demo-form-inline">
    <el-form-item label="用户名">
      <el-input v-model="formInline.user" placeholder="请输入用户名" />
    </el-form-item>
    <el-form-item label="活动区域">
      <el-select v-model="formInline.region" placeholder="请选择活动区域">
        <el-option label="区域一" value="shanghai" />
        <el-option label="区域二" value="beijing" />
      </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 formInline = reactive({
  user: '',
  region: ''
})
const onSubmit = () => {
  console.log('查询:', formInline)
}
</script>对齐方式 
根据你们的设计情况,来选择最佳的标签对齐方式。通过设置 label-position 属性可以改变表单域标签的位置,可选值为 top、left,当设为 top 时标签会置于表单域的顶部。
<template>
  <el-radio-group v-model="labelPosition" size="small">
    <el-radio-button label="left">左对齐</el-radio-button>
    <el-radio-button label="right">右对齐</el-radio-button>
    <el-radio-button label="top">顶部对齐</el-radio-button>
  </el-radio-group>
  
  <el-form
    :label-position="labelPosition"
    label-width="100px"
    :model="formLabelAlign"
    style="max-width: 460px"
  >
    <el-form-item label="姓名">
      <el-input v-model="formLabelAlign.name" />
    </el-form-item>
    <el-form-item label="活动区域">
      <el-input v-model="formLabelAlign.region" />
    </el-form-item>
    <el-form-item label="活动形式">
      <el-input v-model="formLabelAlign.type" />
    </el-form-item>
  </el-form>
</template>
<script setup>
import { reactive, ref } from 'vue'
const labelPosition = ref('right')
const formLabelAlign = reactive({
  name: '',
  region: '',
  type: ''
})
</script>表单验证 
Form 组件允许你验证用户的输入是否符合规范,来帮助你找到和纠正错误。Form 组件提供了表单验证的功能,只需为 rules 属性传入约定的验证规则,并将 form-Item 的 prop 属性设置为需要验证的特殊键值即可。
<template>
  <el-form
    ref="ruleFormRef"
    :model="ruleForm"
    :rules="rules"
    label-width="120px"
    class="demo-ruleForm"
    status-icon
  >
    <el-form-item label="用户名" prop="name">
      <el-input v-model="ruleForm.name" />
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input v-model="ruleForm.password" type="password" />
    </el-form-item>
    <el-form-item label="确认密码" prop="checkPassword">
      <el-input v-model="ruleForm.checkPassword" type="password" />
    </el-form-item>
    <el-form-item label="邮箱" prop="email">
      <el-input v-model="ruleForm.email" />
    </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 { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
const ruleFormRef = ref<FormInstance>()
const validatePass = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  } else {
    if (ruleForm.checkPassword !== '') {
      if (!ruleFormRef.value) return
      ruleFormRef.value.validateField('checkPassword', () => null)
    }
    callback()
  }
}
const validatePass2 = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请再次输入密码'))
  } else if (value !== ruleForm.password) {
    callback(new Error('两次输入密码不一致!'))
  } else {
    callback()
  }
}
const ruleForm = reactive({
  name: '',
  password: '',
  checkPassword: '',
  email: ''
})
const rules = reactive<FormRules>({
  name: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 15, message: '长度在 3 到 15 个字符', trigger: 'blur' }
  ],
  password: [{ validator: validatePass, trigger: 'blur' }],
  checkPassword: [{ validator: validatePass2, trigger: 'blur' }],
  email: [
    { required: true, message: '请输入邮箱地址', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
  ]
})
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log('提交成功!', ruleForm)
    } else {
      console.log('验证失败!', fields)
    }
  })
}
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
</script>尺寸控制 
表单中的所有子组件都继承了该表单的 size 属性。同样,form-item 也有一个 size 属性。如果希望某个表单项或某个表单组件的尺寸不同于 Form 上的 size 属性,直接为这个表单项或表单组件设置自己的 size 属性即可。
<template>
  <el-form :model="sizeForm" size="large" label-width="120px">
    <el-form-item label="用户名">
      <el-input v-model="sizeForm.name" />
    </el-form-item>
    <el-form-item label="活动区域" size="default">
      <el-select v-model="sizeForm.region" placeholder="请选择活动区域">
        <el-option label="区域一" value="shanghai" />
        <el-option label="区域二" value="beijing" />
      </el-select>
    </el-form-item>
    <el-form-item label="活动时间" size="small">
      <el-date-picker
        v-model="sizeForm.date"
        type="date"
        placeholder="选择日期"
      />
    </el-form-item>
  </el-form>
</template>
<script setup>
import { reactive } from 'vue'
const sizeForm = reactive({
  name: '',
  region: '',
  date: ''
})
</script>API 
Form Attributes 
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| model | 表单数据对象 | object | — | 
| rules | 表单验证规则 | object | — | 
| inline | 行内表单模式 | boolean | false | 
| label-position | 表单域标签的位置,当设置为 left 或 right 时,则也需要设置 label-width 属性 | enum | right | 
| label-width | 标签的长度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。可以使用 auto。 | string / number | '' | 
| label-suffix | 表单域标签的后缀 | string | '' | 
| hide-required-asterisk | 是否隐藏必填字段标签旁边的红色星号。 | boolean | false | 
| require-asterisk-position | 星号的位置。 | enum | left | 
| show-message | 是否显示校验错误信息 | boolean | true | 
| inline-message | 是否以行内形式展示校验信息 | boolean | false | 
| status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | false | 
| validate-on-rule-change | 是否在 rules 属性改变后立即触发一次验证 | boolean | true | 
| size | 用于控制该表单内组件的尺寸 | enum | — | 
| disabled | 是否禁用该表单内的所有组件。如果设置为 true,它将覆盖内部组件的 disabled 属性 | boolean | false | 
| scroll-to-error | 当校验失败时,滚动到第一个错误表单项 | boolean | false | 
Form Events 
| 名称 | 说明 | 类型 | 
|---|---|---|
| validate | 任一表单项被校验后触发 | Function | 
Form Exposes 
| 名称 | 说明 | 类型 | 
|---|---|---|
| validate | 对整个表单的内容进行验证。接收一个回调函数,或返回 Promise。 | Function | 
| validateField | 验证具体的某个字段。 | Function | 
| resetFields | 重置该表单项,将其值重置为初始值,并移除校验结果 | Function | 
| scrollToField | 滚动到指定的字段 | Function | 
| clearValidate | 清理某个字段的表单验证信息。 | Function | 
FormItem Attributes 
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| prop | model 的键名。它可以是一个属性的值 | string | — | 
| label | 标签文本 | string | — | 
| label-width | 表单域标签的宽度,例如 '50px'。支持 auto。 | string / number | '' | 
| required | 是否为必填项,如不设置,则会根据校验规则确认 | boolean | false | 
| rules | 表单验证规则,具体配置见下表,更多内容可以参考async-validator | object / array | — | 
| error | 表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息。 | string | — | 
| show-message | 是否显示校验错误信息 | boolean | true | 
| inline-message | 是否在行内显示校验信息 | boolean | false | 
| size | 用于控制该表单域下组件的默认尺寸 | enum | — | 
实践练习 
练习1:用户注册表单 
创建一个完整的用户注册表单,包含以下字段:
- 用户名(必填,3-15个字符)
- 密码(必填,6-20个字符)
- 确认密码(必填,与密码一致)
- 邮箱(必填,邮箱格式)
- 手机号(必填,手机号格式)
- 年龄(可选,18-100岁)
练习2:表单布局实践 
实现不同布局的表单:
- 垂直布局表单
- 行内表单
- 标签在顶部的表单
- 混合布局表单
练习3:动态表单 
实现一个可以动态添加和删除表单项的表单,例如:
- 联系人列表(可添加多个联系人)
- 技能列表(可添加多个技能)
常见问题 
1. 表单验证不生效 
确保:
- el-form设置了- :rules属性
- el-form-item设置了- prop属性
- prop的值与- rules中的键名一致
2. 表单重置不完全 
使用 resetFields() 方法重置表单,确保表单项都有 prop 属性。
3. 自定义验证规则 
const validateCustom = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请输入内容'))
  } else if (value.length < 3) {
    callback(new Error('长度不能少于3个字符'))
  } else {
    callback()
  }
}总结 
Form 表单是 Element Plus 中最重要的组件之一,掌握表单的使用对于构建完整的应用程序至关重要。重点要理解:
- 表单结构:el-form+el-form-item的组合
- 数据绑定:使用 v-model绑定表单数据
- 表单验证:配置 rules和prop实现验证
- 表单操作:提交、重置、清空等操作
- 用户体验:合理的布局和反馈机制
通过不断练习和实践,你将能够熟练使用 Form 组件构建各种复杂的表单应用。