Search code examples
javascripttypescriptvue.jsvue-componentvuex

How to access Vuex store from javascript/typescript modules files (import/export)?


I have a vue application.

How to access the store from javascript/typescript modules files (import/export)?

for example, I create auth-module that export state, actions, mutations.

export const auth = {
  namespaced: true,
  state,
  actions,
  mutations,
  getters,
};

In my app I import the module to my store:

Vue.use(Vuex);

export const store = new Vuex.Store({

  modules: {
    auth,
  }
});

Now, I want to create interceptor (inside my auth-module) for my http calls to add the token from the store.

Vue.http.interceptors.push((request: any) => {
    // ---> store.state.token???
    // request.headers.set('Authorization', 'Bearer TOKEN');
  });

But how can I get access to the state of the store without be depend on my app? import {store} from './store' but it's okay to import the store instance from vue or vuex module.


Solution

  • You can do that using Plugin.

    1. When you using Plugin, you will get the store instance.
    2. Subscribe to the instance and you get the state, extract token from the state and save it to local variable.
    3. In the Interceptor read this module-global variable.

    Here is the solution I built for you:

    StoreTokenInterceptorPlugin.ts

    import Vue from 'vue';
    import VueResource from 'vue-resource';
    import { get } from 'lodash';
    
    Vue.use(VueResource);
    
    export const StoreTokenInterceptorPlugin = (store: any) => {
      let token: string | null = null;
    
      (Vue.http.interceptors as any).push((request: any) => {
        if (token && !request.headers.get('Authorization')) {
          request.headers.set('Authorization', `Bearer ${token}`);
        }
      });
    
      store.subscribe((mutation: any, state: any) => {
        token = get(state, 'auth.token') || null;
      });
    };
    

    in your app store:

    import Vue from 'vue';
    import Vuex from 'vuex';
    
    import { auth, StoreTokenInterceptorPlugin } from '@modules/auth';
    
    Vue.use(Vuex);
    
    export const store = new Vuex.Store({
      state,
    
      modules: {
        auth,
      } as any,
      ....
      plugins: [StoreTokenInterceptorPlugin],
    });