VueJS中登录成功后如何更新导航栏?
解决方案:登录后导航栏动态更新问题
不用Vuex的快速解决方法
方案1:监听路由变化自动检查登录状态
因为登录后你会通过$router.push('/')跳转页面,路由发生变化时可以让导航栏重新校验登录状态:
修改Navbar.vue的代码:
<script> export default { data() { return { notLoggedInDropDown: false, loggedInDropDown: false, logged: false, user : {} } }, methods: { checkLoginStatus() { const userStr = localStorage.getItem('user'); this.logged = !!userStr; // 转换为布尔值 this.user = userStr ? JSON.parse(userStr) : {}; }, closeSession() { localStorage.removeItem('user'); localStorage.removeItem('token'); this.checkLoginStatus(); // 登出后也调用校验方法 }, }, watch: { // 监听路由变化,每次跳转后重新检查登录状态 '$route'() { this.checkLoginStatus(); } }, mounted() { this.checkLoginStatus(); // 初始化时校验 }, } </script>
方案2:用mitt实现全局事件通知
之前用mitt没成功可能是没全局注册事件总线,按以下步骤操作:
- 安装mitt:
npm install mitt
- 在
main.js中注册全局事件发射器:
import mitt from 'mitt'; const emitter = mitt(); Vue.prototype.$emitter = emitter;
- 修改
Login.vue的登录方法,触发登录成功事件:
async signIn(){ try { const data = await login(this.username, this.password) localStorage.setItem('user', JSON.stringify(data.user)) localStorage.setItem('token', data.token) this.$emitter.emit('user-logged-in', data.user); // 通知全局登录成功 this.$router.push('/') } catch (error) { this.error.status = true this.error.message = "Username or password failed." } }
- 修改
Navbar.vue监听事件:
<script> export default { data() { return { notLoggedInDropDown: false, loggedInDropDown: false, logged: false, user : {} } }, methods: { checkLoginStatus() { const userStr = localStorage.getItem('user'); this.logged = !!userStr; this.user = userStr ? JSON.parse(userStr) : {}; }, closeSession() { localStorage.removeItem('user'); localStorage.removeItem('token'); this.checkLoginStatus(); }, }, mounted() { this.checkLoginStatus(); // 监听登录成功事件 this.$emitter.on('user-logged-in', (user) => { this.logged = true; this.user = user; }); }, beforeDestroy() { // 销毁组件前移除监听,避免内存泄漏 this.$emitter.off('user-logged-in'); } } </script>
集成Vuex的方案(适合后续状态管理扩展)
如果你的应用后续需要管理更多全局状态,Vuex是更规范的选择,集成步骤如下:
- 安装Vuex:
npm install vuex
- 在
src目录下创建store/index.js:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { user: JSON.parse(localStorage.getItem('user')) || null, token: localStorage.getItem('token') || null }, mutations: { SET_USER(state, user) { state.user = user; localStorage.setItem('user', JSON.stringify(user)); }, SET_TOKEN(state, token) { state.token = token; localStorage.setItem('token', token); }, LOGOUT(state) { state.user = null; state.token = null; localStorage.removeItem('user'); localStorage.removeItem('token'); } }, actions: { async login({ commit }, { username, password }) { const data = await login(username, password); commit('SET_USER', data.user); commit('SET_TOKEN', data.token); return data; }, logout({ commit }) { commit('LOGOUT'); } }, getters: { isLoggedIn: state => !!state.user } });
- 在
main.js中引入并使用store:
import store from './store'; new Vue({ router, store, render: h => h(App) }).$mount('#app');
- 修改
Login.vue的登录方法:
async signIn(){ try { await this.$store.dispatch('login', { username: this.username, password: this.password }); this.$router.push('/'); } catch (error) { this.error.status = true; this.error.message = "Username or password failed."; } }
- 修改
Navbar.vue,直接从Vuex获取状态:
<script> export default { data() { return { notLoggedInDropDown: false, loggedInDropDown: false } }, computed: { logged() { return this.$store.getters.isLoggedIn; }, user() { return this.$store.state.user || {}; } }, methods: { closeSession() { this.$store.dispatch('logout'); } } } </script>
内容的提问来源于stack exchange,提问作者Ernesto Valencia
相关产品推荐
相关产品推荐

