找回密码
 立即注册
首页 业界区 业界 Vue 3 后端错误消息处理范例

Vue 3 后端错误消息处理范例

支智敏 2025-6-6 15:39:51
1. 错误消息格式

前后端消息传递时,我们可以通过 json 的 errors 字段传递错误信息,一个比较好的格式范例为:
  1. {
  2.   errors: {
  3.     global: ["网络错误"],
  4.     password: ["至少需要一个大写字母", "至少需要八位字符"]
  5.   }
  6. }
复制代码
errors 中,字段名代表出错位置(如果是输入框的话,对应错误要显示在框下面),内容为一个数组,每个字符串代表一个错误。
2. 处理函数

可以新建一个 composables 文件夹,以存储各个 components 中共用的逻辑,例如错误消息处理。这里在 composables 文件夹中新建一个 error.ts:
  1. import { ref, type Ref } from 'vue';
  2. export interface ErrorFields {
  3.   global: string[];
  4.   [key: string]: string[];
  5. }
  6. export function useErrorFields(fields: string[]) {
  7.   const errors: Ref<ErrorFields> = ref({ global: [], ...fields.reduce((acc, field) => ({ ...acc, [field]: [] }), {}) });
  8.   const clearErrors = () => {
  9.     for (const field in errors.value) {
  10.       errors.value[field] = [];
  11.     }
  12.   };
  13.   const hasErrors = (field?: string) => {
  14.     if (field) {
  15.       return errors.value[field].length > 0;
  16.     }
  17.     return Object.values(errors.value).some((field) => field.length > 0);
  18.   };
  19.   const addError = (field: string, message: string) => {
  20.     if (field === '') {
  21.       field = 'global';
  22.     }
  23.     const array = errors.value[field];
  24.     if (!array.includes(message)) {
  25.       array.push(message);
  26.     }
  27.     return array;
  28.   };
  29.   const removeError = (field: string, message?: string) => {
  30.     if (field === '') {
  31.       field = 'global';
  32.     }
  33.     if (message) {
  34.       errors.value[field] = errors.value[field].filter((m) => m !== message);
  35.     } else {
  36.       errors.value[field] = [];
  37.     }
  38.   };
  39.   return { errors, clearErrors, hasErrors, addError, removeError };
  40. }
复制代码
这里我们就定义了错误类及其处理函数。
3. 组件中的使用

定义的 useErrorFields 工具可以在 component 中这样使用:
  1. <template>
  2.   
  3.    
  4.       <p >错误</p>
  5.    
  6.     <ul >
  7.       <li v-for="e in errors.global" v-html="e" />
  8.     </ul>
  9.   
  10.   <form>
  11.    
  12.       <label for="username" >
  13.         用户名
  14.         *
  15.       </label>
  16.       
  17.         <input
  18.           v-model="username"
  19.           @focus="clearErrors"
  20.           id="username"
  21.           name="username"
  22.           type="text"
  23.           autocomplete="username"
  24.           required
  25.          
  26.           :
  27.         />
  28.       
  29.       <ul >
  30.         <li v-for="e in errors.username" v-html="e" />
  31.       </ul>
  32.    
  33.    
  34.       <button
  35.         type="submit"
  36.         
  37.         :
  38.       >
  39.       <button
  40.   type="submit"
  41.   
  42.   :
  43. >
  44.   注册
  45. </button>
  46.       </button>
  47.    
  48.   </form>
  49. </template>
复制代码
接下来,我们一步步解析以上代码。
3.1 根据后端响应更新错误状态

我们首先使用 useErrorFields 定义了一个错误状态类:
  1. const { errors, clearErrors, addError, hasErrors } = useErrorFields(['username', 'password']);
复制代码
这时候,错误状态 errors 中可访问三个字段,并将绑定到页面的不同位置:
global: 全局错误 / 无具体位置的错误 => 显示在表格顶端的单独框中
username: 用户名上的错误 => 显示在 username 输入框下方
password: 密码上的错误 => 显示在 password 输入框下方
接下来,我们需要定义提交函数,例如这里使用 axios 进行后端访问,后端地址用环境变量提供:
  1. function onSubmit() {
  2.   const api = axios.create({
  3.     baseURL: import.meta.env.VITE_API_URL,
  4.   });
  5.   api.get("/user/register")
  6.   .catch((error) => {
  7.     if (error.response && error.response.data && error.response.data.errors) {
  8.       errors.value = { ...errors.value, ...error.response.data.errors };
  9.     } else if (error.response) {
  10.       addError('', '未知错误');
  11.     } else {
  12.       addError('', '网络错误');
  13.     }
  14.   })
  15. }
复制代码
这样,后端返回错误信息时,错误状态会被自动更新。如果出现了网络错误或其他错误,addError类会在 global 字段上增加错误 (使用空字符串为第一个参数,默认添加到 global 字段)。
接下来,将错误状态绑定到页面。
3.2 绑定到输入框
  1. [/code]这里主要使用了两个个函数:
  2. [indent][b]clearErrors[/b]: 当重新开始进行输入时,清除错误状态中的全部错误。
  3. [/indent][indent][b]hasErrors[/b]: 当对应位置出现错误时,将输入框边框颜色变为红色。
  4. [/indent]将错误状态显示在输入框下:
  5. [code]  <label for="username" >
  6.     用户名
  7.     *
  8.   </label>
  9.   
  10.     <input
  11.       ...
  12.     />
  13.   
  14.   <ul >
  15.     <li v-for="e in errors.username" v-html="e" />
  16.   </ul>
复制代码
这里我们使用  标签,使用 errors.username 将对应位置的错误消息依次显示在输入框下。
3.4 全局消息显示在表格顶端
  1.   
  2.     <p >错误</p>
  3.   
  4.   <ul >
  5.     <li v-for="e in errors.global" v-html="e" />
  6.   </ul>
  7. <form>
  8.   ...
  9. </form>
复制代码
这里使用 hasErrors('global') 来检测是否有全局错误,并在输入表顶端显示。
3.5 提交按钮在有错误时不允许点击
  1. <button
  2.   type="submit"
  3.   
  4.   :
  5. >
  6.   注册
  7. </button>
复制代码
这里使用 hasErrors() 来检测错误状态类中是否有任何错误,并据此启用或禁用按钮。
4. 完整案例

如果你需要一个完整案例,这里有:错误状态处理在用户注册场景的案例,前端开源,详见:Github,你也可以访问 Githubstar.pro 来查看网页的效果(一个 Github 互赞平台,前端按本文方式进行错误处理)。
感谢阅读,如果本文对你有帮助,可以订阅我的博客,我将继续分享前后端全栈开发的相关实用经验。祝你开发愉快

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册