VueJS 3,在路由器中访问 Vuex 存储变量的更好方法?

问题描述 投票:0回答:1

使用 Vue.js3,我已在一个组件中成功登录 Google Firebase 身份验证,然后使用以下方法将 Firebase 用户变量存储在 Vuex 存储中:

 store.commit('setUser', userData);

之后,我可以在另一个组件中访问它:

const currentUser = computed(() => store.getters.currentUser);

但是,我无法使用上述方法在 router.js 文件中检索此用户变量。 我当前的解决方法是为商店创建一个操作,一个像这样的异步 fetchUser 函数。它不断尝试检索 Firebase 用户变量、提交并返回。如果没有 Promise 计时器 setTimeout,即使我使用异步等待,它也会立即返回 Null 值。

// store/index.js

import { createStore } from 'vuex';

const store = createStore({
  state: {
    user: null,
   
  },
  mutations: {
    setUser(state, user) {
      state.user = user;
    },
  
  },
  actions: {
    async fetchUser({ commit }) {
      try {
        let fetchedUser = this.getters.currentUser;
        let elapsedTime = 0;
        const maxWaitTime = 10000; // 10 seconds
       
        while (!fetchedUser && elapsedTime < maxWaitTime) {
          fetchedUser = this.getters.currentUser;
          elapsedTime += 200;
          await new Promise(resolve => setTimeout(resolve, 50));
        }

        if (!fetchedUser) {
         
          throw new Error('Timeout: Unable to fetch user within 10 seconds.');
        }
     
        commit('setUser', fetchedUser);
        return fetchedUser;
      } catch (error) {
        console.error('Error fetching user:', error);
        throw error; 
      }
    },

  },
  getters: {
    currentUser: state => state.user,

  },
});

export default store;

我的 router.js 文件:

const routes = [ 
  {
    path: '/',
    name: 'HomePage',
    component: HomePage,
    beforeEnter: async (to, from, next) => {
      const store = useStore();

      try {     
        await store.dispatch('fetchUser');       
        const currentUser =  await store.state.user;    
        if (!currentUser) {        
        // redirect to GoogleLogin page
          next({ name: 'GoogleLogin' });
        } else {
        // Stay at homepage
          next();
        }
      } catch (error) {
        console.error('Error fetching user:', error);       
        next();
      }
    }
  },
  {
    path: '/login',
    name: 'GoogleLogin',
    component: GoogleLogin    
  },
  ];

虽然此解决方法有效,但性能很差,通常需要 800 毫秒才能获取。 是的,或者,我可以向 Router.js 添加另一个 onAuthStateChanged 或在 Main.js 的 onAuthStateChanged 上推送 router.push 来检查并重定向登录页面。

 firebaseAuth.onAuthStateChanged((userData) => {      
          store.commit('setUser', userData);
          console.log('Login check: ', userData);
          if (!userData) {   
            router.push('/login'); // in main.js file

            //next({ name: 'GoogleLogin' }); // if use in router.js
          } else {    

            //...
          }
        });

但有时,我仍然需要在 Router.js 中使用 Vuex 变量,那么我该如何改进这一点,或者是否有更好的方法在 Router 文件中使用 Vuex 全局变量?

vue.js vuex router store
1个回答
0
投票

对我来说,使用 Vuex store 到 router.js 中是最好的方法,因为这是直接导入并使用它来访问状态的最直接的方法。

import store from './store'; // Import your Vuex store

   router.beforeEach((to, from, next) => {
     const currentUser = store.getters.currentUser;
     if (!currentUser) {
       next({ name: 'GoogleLogin' });
     } else {
       next();
     }
   });

© www.soinside.com 2019 - 2024. All rights reserved.