基于AWS Amplify登录状态的Vue3导航栏条件渲染异常排查
解决Vue3 + AWS Amplify登出后导航栏不更新的问题
问题根源
- 计算属性返回Promise而非布尔值:
isSignedIn计算属性返回的是异步函数isUser()的Promise对象,Vue无法将Promise直接作为布尔值用于v-show判断,导致初始渲染可能生效,但状态更新时无法响应。 - Watch配置位置错误:你把
watch写在了computed对象内部,这是无效的,Vue无法识别该监听逻辑。 - 未监听Auth状态变化:AWS Amplify的Auth状态变化(比如登出)不会主动通知组件,需要手动监听Auth的状态事件来更新本地状态。
修复步骤
- 在
data中添加isSignedIn状态变量,存储当前登录状态。 - 初始化时调用
Auth.currentAuthenticatedUser获取初始登录状态,更新isSignedIn。 - 使用Amplify的
Hub监听Auth模块的signIn、signOut等事件,实时更新登录状态。 - 移除错误的计算属性和无效的watch配置,直接使用data中的
isSignedIn做条件渲染。
修改后的完整代码
<template> <header> <nav class="navbar"> <router-link @click="closeMenu" to="/" class="nav-branding" >Portal</router-link > <ul :class="[menuIsOpen ? 'active' : '', 'nav-menu']" v-show="isSignedIn"> <li @click="toggleMenu" class="nav-item"> <router-link to="/pensions" class="nav-link">Pensions</router-link> </li> <li @click="toggleMenu" class="nav-item"> <router-link to="/benefits" class="nav-link">Benefits</router-link> </li> <li @click="toggleMenu" class="nav-item"> <router-link to="/annual-leave" class="nav-link" >Annual Leave</router-link > </li> <li @click="signOut" class="nav-item"> <router-link to="/" class="nav-link">Sign Out</router-link> </li> </ul> <div @click="toggleMenu" :class="[menuIsOpen ? 'active' : '', 'hamburger']" v-show="isSignedIn" > <span class="bar"></span> <span class="bar"></span> <span class="bar"></span> </div> </nav> </header> <div :class="[menuIsOpen ? 'pushed' : 'static']"></div> </template> <script> import { Auth, Hub } from "aws-amplify"; export default { name: "NavBar", data() { return { menuIsOpen: false, isSignedIn: false }; }, async mounted() { // 初始化获取登录状态 await this.checkAuthStatus(); // 监听Auth状态变化 Hub.listen('auth', (data) => { const { payload } = data; if (payload.event === 'signIn' || payload.event === 'signOut') { this.checkAuthStatus(); } }); }, methods: { toggleMenu() { this.menuIsOpen = !this.menuIsOpen; }, closeMenu() { this.menuIsOpen = false; }, async signOut() { try { await Auth.signOut(); this.$router.push("/"); } catch (err) { console.log(err); } }, async checkAuthStatus() { try { await Auth.currentAuthenticatedUser(); this.isSignedIn = true; } catch { this.isSignedIn = false; } } } }; </script> <style> header { height: auto; background-color: #0d1520; } li { list-style: none; } a { color: white; text-decoration: none; } .navbar { min-height: 70px; display: flex; justify-content: space-between; align-items: center; padding: 0 24px; } .nav-menu { display: flex; justify-content: space-around; align-items: center; gap: 60px; } .nav-branding { font-size: 2rem; color: #03e9f4; } .nav-branding:hover { text-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 100px #03e9f4; } .nav-link { transition: 0.7s ease; color: #03e9f4; } .nav-link:hover { text-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 100px #03e9f4; } .hamburger { display: none; cursor: pointer; } .bar { display: block; width: 25px; height: 3px; margin: 5px auto; transition: all 0.3s ease-in-out; background-color: #03e9f4; } .hamburger:hover .bar { box-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 100px #03e9f4; } @media (max-width: 768px) { .static { transition: all 0.5s ease-in-out; padding-top: 0; z-index: 0; background-color: #151f31; } .pushed { padding-top: 168px; transition: padding 0.3s ease-in-out; transition-delay: 0.2; z-index: 0; background-color: #151f31; } .hamburger { display: block; } .hamburger.active .bar:nth-child(2) { opacity: 0; } .hamburger.active .bar:nth-child(1) { transform: translateY(8px) rotate(45deg); } .hamburger.active .bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); } .nav-menu { position: fixed; left: 100%; top: 70px; gap: 0; flex-direction: column; background-color: #0d1520; width: 100%; text-align: center; transition: 0.5s; } .nav-item { margin: 16px 0; } .nav-menu.active { z-index: 1; left: 0; } } </style>
说明
- 新增
checkAuthStatus方法统一处理登录状态检查,更新响应式的isSignedIn变量。 - 在
mounted钩子中初始化状态,并通过Hub.listen监听Auth模块的状态变化,确保登录/登出操作实时同步组件状态。 - 移除了无效的计算属性和错误放置的watch配置,直接使用
isSignedIn变量完成条件渲染。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

