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

相关推荐
极小狐14 分钟前
极狐GitLab 容器镜像仓库功能介绍
java·前端·数据库·npm·gitlab
程序猿阿伟26 分钟前
《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
前端·flutter
rafael(一只小鱼)30 分钟前
黑马点评实战笔记
前端·firefox
weifont30 分钟前
React中的useSyncExternalStore使用
前端·javascript·react.js
初遇你时动了情35 分钟前
js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
前端·javascript·react.js
影子信息1 小时前
css 点击后改变样式
前端·css
几何心凉1 小时前
如何使用 React Hooks 替代类组件的生命周期方法?
前端·javascript·react.js
小堃学编程1 小时前
前端学习(1)—— 使用HTML编写一个简单的个人简历展示页面
前端·javascript·html
hnlucky2 小时前
通俗易懂版知识点:Keepalived + LVS + Web + NFS 高可用集群到底是干什么的?
linux·前端·学习·github·web·可用性测试·lvs
懒羊羊我小弟2 小时前
使用 ECharts GL 实现交互式 3D 饼图:技术解析与实践
前端·vue.js·3d·前端框架·echarts