Vue.js + PHP登录模块Snackbar错误消息不显示问题求助
搞定登录错误提示的Snackbar问题
嘿,我看了你的代码,发现Snackbar没法正常弹错误提示,核心问题出在后端PHP的错误响应逻辑没写对,导致前端Axios没抓到错误信号,自然触发不了Snackbar。下面一步步给你拆解问题和修复方案:
一、先把PHP的坑填上
你的PHP代码在处理错误场景时,要么没返回正确的响应,要么破坏了JSON格式,直接导致前端收不到有效的错误提示:
账户不存在时,啥都没返回
当查到邮箱对应的账户不存在时,你只是给$error赋值然后直接die()了,这时候前端收到的是空的200成功响应,Axios根本不会进入catch块,当然不会触发Snackbar。密码错误时,输出了多余的HTML标签
你调用的console_log函数会输出<script>标签,这会把JSON响应搞乱,Axios解析不了,就算你设了500状态码也没用。状态码用错了
500是服务器内部错误,登录失败属于客户端输入问题,用401(未授权)或者400(请求错误)更合适。
修复后的PHP代码
<?php require_once("connection.php"); $data = json_decode(file_get_contents("php://input"), true); // 检查账户是否存在 $sql = $handler->prepare("SELECT * FROM accounts WHERE email = ?"); $sql->execute(array($data['email'])); $count = $sql->rowCount(); if($count === 1) { $info = $sql->fetch(PDO::FETCH_OBJ); $verified = password_verify($data['password'], $info->password); if ($verified) { // 登录成功,返回用户数据 $accountData = new \stdClass(); $accountData->uid = $info->uid; $accountData->displayName = $info->fname . ' ' . $info->lname; $accountData->email = $info->email; $accountData->type = $info->type; header("HTTP/1.1 200 OK"); header('Content-Type: application/json; charset=UTF-8'); die(json_encode($accountData)); } else { // 密码错误,返回401和具体提示 header('HTTP/1.1 401 Unauthorized'); header('Content-Type: application/json; charset=UTF-8'); die(json_encode(array( 'message' => 'Wrong email or password. Please try again.', 'code' => 2000 ))); } } else { // 账户不存在,返回400和具体提示 header('HTTP/1.1 400 Bad Request'); header('Content-Type: application/json; charset=UTF-8'); die(json_encode(array( 'message' => 'Account does not exist under this email. Please try again.', 'code' => 2001 ))); } // 删掉这个后端输出前端console的函数,它会破坏响应格式 // function console_log($output, $with_script_tags = true) { ... } ?>
二、再优化Vue的错误捕获逻辑
原来的Vue代码里,你不管啥错误都传"incorrect"给Snackbar,而且可以优化下错误信息的获取,让用户看到更准确的提示:
修复后的signIn方法
signIn () { if (this.$refs.login.validate()) { this.loading.login = true axios.post('./sql/login.php', this.form) .then((res) => { const data = res.data console.log(data) // 登录成功,存储用户信息并跳转 sessionStorage.setItem('uid', data.uid) sessionStorage.setItem('displayName', data.displayName) sessionStorage.setItem('email', data.email) sessionStorage.setItem('type', data.type) if (data.type === 'customer') { router.push('/'); // 这里建议去掉location.reload(),强制刷新会打断路由跳转逻辑 // 如果需要更新页面数据,用Vue的响应式数据或者Vuex来处理 } else if (data.type === 'seller') { router.push('/seller') } this.loading.login = false }) .catch((error) => { console.log(error); // 优先取后端返回的错误信息,没有就用默认提示 const errorMsg = error.response?.data?.message || 'Login failed. Please try again.'; this.$emit('snackbar', errorMsg); this.loading.login = false }) } }
三、最后要检查的两个点
- 确认父组件正确监听了
snackbar事件,并且Snackbar组件能正确接收消息并显示。 - 打开浏览器的Network面板,看看登录请求的响应:状态码是不是4xx,响应内容是不是纯JSON(没有多余的HTML标签)。
这样改完,应该就能正常弹出错误提示了~
内容的提问来源于stack exchange,提问作者Kim Bryan
相关产品推荐
相关产品推荐

