【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 的应用和区别

相关推荐
郭老二5 小时前
【前端】vue3:编译步骤
前端
不在逃避q6 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁6 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9856 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易6 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师7 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174468 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈8 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen9 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒9 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端