Vue.js 3中在Router中访问Vuex Store变量的优化方案
Vue.js 3中在Router高效访问Vuex用户状态的解决方案
方法1:先同步Auth状态再挂载应用
在项目入口main.js中,先等待Firebase Auth完成状态同步,再挂载Vue实例和路由,确保路由初始化时Vuex已持有用户数据:
// main.js import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import { getAuth, onAuthStateChanged } from "firebase/auth"; const auth = getAuth(); const app = createApp(App); // 监听Auth状态变化,同步到Vuex后再挂载应用 onAuthStateChanged(auth, (user) => { store.commit('setUser', user || null); // 状态就绪后完成应用挂载 app.use(store).use(router).mount('#app'); });
这样在router.js中可直接访问store.getters.currentUser,无需轮询。
方法2:路由守卫中结合Auth监听和Vuex同步
在路由守卫里通过Firebase的onAuthStateChanged一次性监听状态,同步到Vuex后再处理路由跳转,避免轮询:
// router.js import { createRouter, createWebHistory } from 'vue-router' import store from './store' import { getAuth, onAuthStateChanged } from "firebase/auth"; const routes = [ { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } }, { path: '/login', component: Login } ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) router.beforeEach((to, from, next) => { const auth = getAuth(); const requiresAuth = to.matched.some(record => record.meta.requiresAuth); if (requiresAuth) { // 监听一次Auth状态,避免内存泄漏 const unsubscribe = onAuthStateChanged(auth, (user) => { unsubscribe(); if (user) { // 若Vuex无用户数据则同步 !store.getters.currentUser && store.commit('setUser', user); next(); } else { next('/login'); } }); } else { next(); } }) export default router
方法3:Vuex初始化时主动获取用户状态
在Vuex Store中添加初始化动作,通过getCurrentUser同步获取当前Auth用户,确保路由启动时状态已就绪:
// store/index.js import { createStore } from 'vuex' import { getAuth, getCurrentUser } from "firebase/auth"; export default createStore({ state: { user: null }, getters: { currentUser: state => state.user }, mutations: { setUser(state, user) { state.user = user; } }, actions: { async initUser({ commit }) { const auth = getAuth(); const user = await getCurrentUser(auth); commit('setUser', user); } } })
然后在main.js中先执行初始化动作再挂载应用:
// main.js // ...其他导入 async function initApp() { await store.dispatch('initUser'); app.use(store).use(router).mount('#app'); } initApp();
原轮询方案的问题
轮询会反复检查状态,既消耗资源又存在固定延迟。而Firebase提供的onAuthStateChanged实时监听、getCurrentUser同步获取,都是官方优化的状态获取方式,效率远高于轮询。
内容的提问来源于stack exchange,提问作者Thi Hoang
相关产品推荐
相关产品推荐

