【Vue3 + ElementUI】表单校验无效(写法:this.$refs[‘formName‘].validate((valid) =>{} ))

一. 表单校验

1.1 template模块

el-form 中 若校验,ref 和 rules 必须要有

bash 复制代码
<template>
	<div style="padding:20px">
		<el-form ref="formName" :model="form" :rules="formRules"  label-width="120px">
			<template v-if="type == '查看'">
				<el-form-item>
          			<el-col :span="12">
           				<el-form-item label="联系人" prop="contactName">
              				<span>{{ form.contactName }}</span>
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="学历" prop="education">
              				<span>{{ form.education}}</span>
            			</el-form-item>
          			</el-col>
        		</el-form-item>
        		<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="手机号" prop="phone">
              				<span>{{ form.phone }}</span>
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="邮箱" prop="email">
              				<span>{{ form.email }}</span>
            			</el-form-item>
          			</el-col>
        		</el-form-item>
			<template>
			<template v-else>
				<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="联系人" prop="contactName">
              				<el-input v-model="form.contactName" placeholder="请输入联系人" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="学历" prop="education">
              				<el-input v-model="form.education" placeholder="请输入学历" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
        		</el-form-item>
        		<el-form-item>
          			<el-col :span="12">
            			<el-form-item label="手机号" prop="phonenumber">
              				<el-input v-model="form.phonenumber" placeholder="请输入手机号" maxlength="11" show-word-limit />
            			</el-form-item>
          			</el-col>
          			<el-col :span="12">
            			<el-form-item label="邮箱" prop="email">
              				<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="20" show-word-limit />
            			</el-form-item>
          			</el-col>
        		</el-form-item>
			<template>
		</el-form>
		<div v-if="type == '修改'">
      		<el-button @click="handleClick">取 消</el-button>
      		<el-button type="primary" @click="handleSubmit">确 认</el-button>
    	</div>
	</div>
</template>

1.2 script 模块

bash 复制代码
<script setup name="Detail">
import { validPhoneNumber, validEmail } from '@/utils/validate'
import { update } from "@/api/xxx"

const { proxy } = getCurrentInstance()
const router = useRouter() // 用于进行路由的导航操作(跳转等)
const route = useRoute() // 获取当前路由的信息
const detailId = route.params.id // 该条数据的唯一主键 id,用于传参
const type = ref('') //  编辑 or 查看

// 监听路由并赋值给type字段(type的值为:查看/修改)
watch(
  () => route.query.type,
  newValue => {
    type.value = newValue
},
  {deep: true, immediate: true}
)

// 定义
const data = reactive({
  form: {},
  rules: {
    contactName: [
    	{ required: true, message: '名称必填', trigger: 'blur' }
    ],
    phonenumber: [
      {
        message: '请输入正确的手机号',
        trigger: 'blur',
        validator(rule, value, callback) {
          if (value && value !== '') {
            if (validPhoneNumber(value)) {
              return true
            } else {
              return false
            }
          } else {
            callback() // 必须返回,不然校验时获取不到vaild的值
          }
        }
      }
    ],
    email: [
      {
        message: '请输入正确的邮箱',
        trigger: 'blur',
        validator(rule, value, callback) {
          if (value !== '' && value !== null) {
            if (validEmail(value)) {
              return true
            } else {
              return false
            }
          } else {
            callback() // 必须返回,不然校验时获取不到vaild的值
          }
        }
      }
    ]
  }
})

// 重置表单
const reset = () => {
  form.value = {
    contactName: '',
    education: '',
    phonenumber: '',
    email: ''
  }
  proxy.resetForm('formName')
}
const { form, rules } = toRefs(data)

/**
 * 点击确认
 */
const submitForm = () => {
  // 详细查看 1.2.1 
}

/**
 * 点击取消:跳转到XXX页(此时会新打开一个标签页。解决办法:router.go(-1))
 */
const handleClick = async () => {
  await router.push({ path: `/xxx` })
}
</script>

1.2.1 校验rules中全部字段

validate

bash 复制代码
/**
 * 点击确认:校验 rules中全部字段
 */
const submitForm = () => {
  console.log('点确认了吗');
  proxy.$refs['formName'].validate(valid => {
    console.log(valid, '是否校验成功');
    if (valid) {
      if (type === '修改') {
         update({ id: detailId, ...form.value }).then(res => {
           if (res.code === 200) {
             proxy.$modal.msgSuccess('修改成功')
             handleClick()
           }
         })
      }
    }
  })
}

遇到的问题

  1. 描述:this.$refs['formName'].validate((valid) =>{} ))无效,即 校验成功但 获取不到valid的值
  2. 打印截图

  3. 原因:rules中 每个字段,在自定义校验规则时 的 validator 中。每个 if 都要对应一个 else ,且每个条件下都要 确保执行 callback
  4. 解决
    ① 解决前

    ② 解决后

1.2.2 校验 rules 中 指定字段

某个字段:validateField('xxx',vaild=>{})
某俩字段:validateField(['xxx', 'xxx'], valid =>{})

bash 复制代码
/**
 * 点击确认:校验 rules中指定字段
 */
const submitForm = () => {
  proxy.$refs['formName'].validateField('phonenumber', valid => {
    if (valid) {
      if (type === '修改') {
        update({ id: detailId, ...form.value }).then(res => {
          if (res.code === 200) {
            proxy.$modal.msgSuccess('修改成功')
            handleClick()
          }
        })
      }
    }
  })
}

二. 校验规则

2.1 邮箱

bash 复制代码
/**
 * @param {string} email
 * @returns {Boolean}
 */
export function validEmail(email) {
  const reg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(com|cn|net)$/
  return reg.test(email)
}

2.2 手机号

bash 复制代码
/**
 * @param {String} phoneNumber
 * @returns {Boolean}
 */
export function validPhoneNumber(phoneNumber) {
  const reg = /^1(3|4|5|7|8|9)\d{9}$/
  return reg.test(phoneNumber)
}

三. 知识点

3.1 useRouter() 和 useRoute() 的区别

3.2 reactive 和 ref 的区别

3.3 el-form 全部校验 和 指定某字段校验

必须确保 callback 的执行

3.4 toRef 和 toRefs 的应用和区别

相关推荐
m0_7482546622 分钟前
AJAX 基础实例
前端·ajax·okhttp
vmiao23 分钟前
【前端入门】商品页放大镜效果(仅放大镜随鼠标移动效果)
前端
持续前行27 分钟前
vscode 中找settings.json 配置
前端·javascript·vue.js
Anita_Sun29 分钟前
Lodash 源码解读与原理分析 - Lodash IIFE 与兼容性处理详解
前端
用户9047066835730 分钟前
Nuxt 请求后端接口怎么写,一篇文章讲清楚
前端
ahubbub33 分钟前
用 maptalks 在 Web 上做可扩展的 2D/3D 地图渲染与交互
前端
JosieBook35 分钟前
【Vue】11 Vue技术——Vue 中的事件处理详解
前端·javascript·vue.js
韩曙亮36 分钟前
【jQuery】jQuery 简介 ( JavaScript 库简介 | jQuery 核心概念、特点 | jQuery 下载并使用 )
前端·javascript·jquery
安逸点38 分钟前
Vue项目中使用xlsx库解析Excel文件
vue.js
一只小阿乐1 小时前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网