Lecture12-表单与校验

文章目录

    [toc]

    单词词性音标含义
    el-formn./el fɔːm/Element Plus 的表单组件,承载表单数据与校验规则
    el-form-itemn./el fɔːm ˈaɪtəm/表单里的单个字段项,负责标红并显示提示
    rulesn./ruːlz/校验规则对象,集中声明每个字段的检查项
    validatev./ˈvælɪdeɪt/触发校验的方法,通过才继续、不过自动提示
    propn./prɒp/字段项绑定的字段名,必须与 form 字段、rules 键一致
    reactiveadj./riˈæktɪv/声明响应式对象的 API,适合整个表单对象
    FormRulesn./fɔːm ruːlz/Element Plus 提供的校验规则类型

    Lecture12-表单与校验

    1、本节讲什么

    学会用 Element Plus 的 el-form 做出带校验的表单——必填、格式检查、提交。这是后台管理系统里用得最多的东西。配图见 assets/request-response.svg(表单提交到后端的流程)。

    2、概念速览

    什么是表单校验:在提交前先检查"用户填得对不对"——必填项是否为空、邮箱格式对不对、密码够不够长。不对就拦住并提示,而不是把脏数据提交给后端。

    谁来做校验:前端用 rules 规则做第一道检查(体验好、快),后端再校验一遍(安全)。前端校验不是可做可不做,是基本体验。

    正确 vs 误区:校验规则是"配置"出来的(rules 对象),不是写在提交函数里一堆 if。把规则集中声明,代码才清晰。

    3、先看效果

    一个登录表单:空着点"登录",弹出"请输入用户名/密码";填错邮箱格式也会拦。

    LoginForm.vue

    <script setup lang="ts">
    import { reactive, ref } from 'vue'
    import { ElMessage } from 'element-plus'
    import type { FormInstance, FormRules } from 'element-plus'
    
    // reactive:像 ref 但适合整个对象,访问不用 .value
    const form = reactive({ username: '', email: '' })
    
    // 校验规则:每个字段的检查项
    const rules: FormRules = {
      username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
      email: [
        { required: true, message: '请输入邮箱', trigger: 'blur' },
        { type: 'email', message: '邮箱格式不对', trigger: 'blur' },
      ],
    }
    const formRef = ref<FormInstance>()
    
    function onSubmit() {
      // validate():触发校验。通过才继续,不过会自动提示
      formRef.value?.validate().then(() => {
        console.log('提交的数据:', form)   // 第 35 节这里会换成调后端接口
        ElMessage.success('校验通过,准备提交!')
      })
    }
    </script>
    
    <template>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px" style="width: 500px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="form.email" />
        </el-form-item>
        <el-button type="primary" @click="onSubmit">登录</el-button>
      </el-form>
    </template>
    

    4、照着做

    1. 建 LoginForm.vue 并引入 App。
    2. 空着点"登录",看是否弹出"请输入用户名"——必填校验生效了。
    3. 填个不是邮箱的内容,看"邮箱格式不对"——格式校验生效了。
    4. 把 trigger: 'blur' 改成 trigger: 'change',体会"失焦时检查"和"输入时检查"的区别。

    5、常见疑问

    • Q:prop 是干嘛的?为什么 rules 的键要跟它对应? A:prop="email" 告诉校验器"这一项对应 form.email",rules 里 email 的规则就作用在这项上。prop 的名字必须和 form 的字段名、rules 的键一致,这是最常见的出错点。
    • Q:校验不过会怎样? A:el-form-item 会自动标红并显示 message,validate() 返回的 Promise 会 reject(不执行 then)。你只需写"校验通过后做什么"。
    • Q:校验规则记不住怎么办? A:记住两种常用:required(必填)和 type: 'email' / 'number'(格式)。复杂的直接让 AI 写,你描述"邮箱必填、格式要对"即可。
    • Q:FormInstance 是什么类型? A:el-form 的实例类型,用来调 validate() 等方法。ref<FormInstance>() 是把模板里的 ref="formRef" 关联起来。

    补充:用正则(pattern)校验复杂格式

    内置的 required、type: 'email' 不够时,可以用校验规则的 pattern 属性写自己的正则。例如把用户名校验改成:只能字母/数字/下划线、长度 5~10 位(含边界)、不能以数字开头:

    const rules: FormRules = {
      username: [
        { required: true, message: '请输入用户名', trigger: 'blur' },
        {
          pattern: /^[a-zA-Z_][a-zA-Z0-9_]{4,9}$/,
          message: '用户名需为5~10位,只能字母/数字/下划线,且不能以数字开头',
          trigger: 'blur',
        },
      ],
    }
    

    正则拆解:

    片段含义
    ^从开头开始匹配
    [a-zA-Z_]第一个字符:字母或下划线(不含数字 → 满足"不能数字开头")
    [a-zA-Z0-9_]{4,9}之后 4~9 位:字母 / 数字 / 下划线
    $一直匹配到结尾

    1 位 + 4~9 位 = 5~10 位,正好满足长度要求(含边界值 5 和 10)。

    简化写法:\w 等价于 [a-zA-Z0-9_],可简写为:

    pattern: /^[a-zA-Z_]\w{4,9}$/,
    

    正确 vs 误区:

    • 长度要写 {4,9} 而不是 {5,10}——因为 {4,9} 是第一个字符之外再补的位数,总长度 = 1 + (4~9) = 5~10;直接写 {5,10} 会变成 6~11 位。
    • "不能数字开头"是把 [0-9] 从第一个字符的字符集里排除,简单直接,不需要用复杂的负向前瞻。
    • 内置的 type: 'email' / 'number' 底层其实也是正则;遇到"既不是邮箱也不是数字"的格式要求,就用 pattern 写自己的正则。

    6、规范要点

    • 表单校验规则集中放在 rules 里,别散落在提交函数里一堆 if。
    • 提交前必调 validate(),别跳过校验直接发请求。
    • 表单数据用 reactive 声明,字段命名清晰、和接口字段对应(第 35 节联调时尤其重要)。

    7、本节验证

    • 会用 el-form + el-form-item 搭出带校验的表单 ✅
    • 会用 rules 做必填(required)和邮箱格式(type: 'email')校验 ✅
    • 会用 pattern 正则做自定义格式校验(如用户名的长度/字符集规则)✅
    • 提交前会调用 validate(),校验不过自动提示 ✅
    • 知道 prop 必须与 form 字段名、rules 键一致 ✅
    end