Laravel Vue+Vuetify:如何在登录错误catch块设置this.loading=false?
解决登录按钮加载状态控制问题
我来帮你搞定这个登录页面的加载状态控制问题!首先得指出你当前代码里的一个小问题:你写了两个.catch()块,但Promise的错误捕获机制是只会执行第一个匹配到的catch块,所以那个提示「Invalid Email or Password」的catch实际上永远不会被触发,而且loading状态的处理也有点分散。
我们可以把错误处理逻辑合并到一个.catch()块里,根据不同的错误类型分别处理,同时确保this.loading = false在所有错误场景下都能执行。下面是修改后的完整代码:
修改后的组件代码
<template> <v-row justify="center"> <v-col cols="12" sm="6"> <form @submit.prevent="login"> <v-card ref="form"> <v-card-text> <h3 class="text-center">Login</h3> <v-divider class="mt-3"></v-divider> <v-col cols="12"> <v-img src="/assets/1.png" class="my-3" contain height="50" /> </v-col> <v-col cols="12" sm="12"> <v-text-field v-model.trim="form.mobile_number" type="number" label="Mobile No" solo hide-details="auto" ></v-text-field> <span class="form-text red--text" v-if="errors.mobile_number"> {{ errors.mobile_number[0] }} </span> </v-col> <v-col cols="12"> <v-text-field v-model.trim="form.password" type="password" label="Password" solo hide-details="auto" append-icon="mdi-eye" ></v-text-field> <span class="form-text red--text" v-if="errors.password"> {{ errors.password[0] }} </span> </v-col> </v-card-text> <v-divider class="mt-12"></v-divider> <v-card-actions> <v-spacer></v-spacer> <div class="text-center"> <v-btn rounded type="submit" :loading="loading" color="primary" dark > Login </v-btn> </div> </v-card-actions> </v-card> </form> </v-col> </v-row> </template> <script> export default { created(){ if (User.loggedIn()) { this.$router.push({name: 'DashBoard'}) } }, data(){ return { loading: false, form:{ mobile_number: null, password: null }, errors:[], }; }, methods:{ login(){ this.loading = true; // 清空之前的错误提示,避免残留 this.errors = []; axios.post('/api/auth/login',this.form) .then(res => { User.responseAfterLogin(res) Toast.fire({ icon: 'success', title: 'Signed in successfully' }) this.$router.push({ name: 'DashBoard'}); }) .catch((error) => { // 统一关闭加载状态,确保任何错误场景下都能生效 this.loading = false; // 根据HTTP状态码区分错误类型 if (error.response.status === 422) { // Laravel默认表单验证错误,显示字段级错误提示 this.errors = error.response.data.errors; } else if (error.response.status === 401) { // 未授权,对应「Invalid Email or Password」场景 Toast.fire({ icon: 'warning', title: 'Invalid Email or Password' }) } else { // 兜底处理其他意外错误 Toast.fire({ icon: 'error', title: 'Something went wrong, please try again later' }) } }) // 可选:保留finally进一步确保loading状态重置,双重保险 .finally(() => { this.loading = false }) } } }; </script>
关键改动说明
- 合并独立的
.catch()块:Promise不支持多个并行的catch块,合并后能统一处理所有错误场景 - 错误发生时立即关闭加载状态:在catch块开头就设置
this.loading = false,确保登录按钮能及时恢复可点击状态 - 按HTTP状态码区分错误场景:
- 状态码
422对应Laravel的表单验证失败,用来显示手机号/密码的字段错误 - 状态码
401对应未授权,正好匹配「Invalid Email or Password」的提示场景
- 状态码
- 添加错误兜底逻辑:处理网络异常、服务器错误等意外情况,提升用户体验
- 登录前清空错误信息:避免上次的错误提示残留,让页面交互更干净
这样修改后,无论是表单验证错误还是无效凭证错误,登录按钮的加载状态都会正确关闭,同时错误提示也能准确显示啦!
内容的提问来源于stack exchange,提问作者user12380208
相关产品推荐
相关产品推荐

