【Vue3】Element Plus 表单显示自定义校验错误

在开发中,遇到这个需求:前端表单通过初步校验发送给后端,但后端业务逻辑(如:数据库查重、时间冲突等)返回了具体的错误信息。业务希望将这些错误直接显示在 el-form-item 的错误提示位置。大概效果如下:

基础校验如下

javascript 复制代码
const rules = ref({
  start_time: [{ required: true, message: "请输入时间", trigger: "blur" }],
  location: [{ required: true, message: "请输入地点", trigger: "blur" }],
  pant: [{ required: true, message: "请输入参与者", trigger: "blur" }],
  evt_desc: [
    { required: true, message: "请请输入描述", trigger: "blur" },
    { min: 0, max: 30, message: "描述不超过 30 个字符", trigger: "blur" },
  ],
});

遇到的问题:

直接给 :error 属性赋值,首次没问题,错误正产显示,但第二次点击提交时校验消息就不再显示了。
原因:

Element Plus 的 el-form-item 提供了 :error 属性。

当给这个属性赋值时,它会强制显示该错误提示,并覆盖原有的 rules 校验信息。

因为form.validate() 是异步过程,其内部维护的校验状态更新可能与手动赋值 :error 的操作产生竞争关系,导致手动赋的值被组件内部逻辑重置。
解决

使用 nextTick(或延时)确保后端错误能稳定渲染

代码示例:

javascript 复制代码
<template>
  <div>
    <el-form ref="formRef" :model="form" :rules="rules" label-position="top">
      
      <el-form-item label="事件描述" prop="evt_desc" :error="backendErrors.evt_desc">
        <el-input v-model="form.evt_desc" placeholder="请输入描述" />
      </el-form-item>

      <el-button type="primary" :loading="loading" @click="handleSubmit">
        开始
      </el-button>
    </el-form>
  </div>
</template>

<script setup>
import { reactive, ref, nextTick } from 'vue';

const formRef = ref();
const loading = ref(false);

// 存储后端返回的错误映射
const backendErrors = reactive({
  evt_desc: ""
});

const form = reactive({
  evt_desc: ""
});

const rules = {
  evt_desc: [{ required: true, message: "前端校验:请输入内容", trigger: "blur" }]
};

// 模拟后端接口
async function mockApi() {
  return new Promise((_, reject) => {
    setTimeout(() => {
      // 模拟后端校验不通过返回的数据
      reject({
        message: JSON.stringify({ evt_desc: "后端反馈:该描述已存在,请更换" })
      });
    }, 500);
  });
}

// 提交逻辑
async function handleSubmit() {
  if (!formRef.value) return;

  formRef.value.validate(async (valid) => {
    if (!valid) return;
    
    loading.value = true;
    try {
      await mockApi();
      // 成功逻辑...
    } catch (err) {
      // 清空旧的后端错误
      Object.keys(backendErrors).forEach(key => backendErrors[key] = "");

      // 解析错误并赋值
      const errorMap = JSON.parse(err.message);
      
      // ==== 这个是关键 ====
      await nextTick(); 
      
      for (const key in errorMap) {
        if (key in backendErrors) {
          backendErrors[key] = errorMap[key];
        }
      }
    } finally {
      loading.value = false;
    }
  });
}
</script>
相关推荐
jerrywus13 分钟前
我用 GPT-6.1-sol 做了台会讲解的 3D 售货机:60 罐饮料,一口没喝上
前端·agent·claude
孟陬1 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端
Highcharts.js2 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
Dream-Y.ocean2 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina3 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源4 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js5 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路5 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员6 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron