0

Currently I'm using Vue + Typescript + Vuex making use of the decorators from vuex-class in my Vue components and organize my files per store module like:

moduleA-store.ts   // state
moduleA-actions.ts
moduleA-mutations.ts
moduleA-getters.ts

What I don't like about that default Vuex setup is the inflexibility like not being able to access an action from module B inside an action of module A.

e.g. receiving a profile picture in an signup action of my "auth" store module whose URL should be written in my user profile handled by an action of my "user" store module

As far as I know there is no way with the default setup to achieve the following; the only thing I can access from anywhere is the various module's state.

It made me think of small changes to overcome this by replacing the current setup which looks something like

auth-actions.ts

export const actions: ActionTree<AuthState, RootState> = { 
    signInWithGoogle({ commit }, payload) {
        // ...
        commit('setWhatever', whatever)
    }
}

auth-mutations.ts

export const mutations: MutationTree<AuthState> = {
    setWhatever(state, whatever) {
        state.whatever = whatever
    }
}

by a more pure, custom (and typesafe) setup like the following

auth-actions.ts

import authMutations from 'auth-mutations.ts'
import userActions from 'user-actions.ts'

export const authActions = {
    async signInWithGoogle(payload) {
        // ...
        authMutations.setWhatever(whatever)
        userActions.setProfileURL(url)
    }
}

auth-mutations.ts

import authState from 'auth-store.ts'

export const authMutations = {
    setWhatever(whatever: string) {
        authState.whatever = whatever
    } 
}

user-actions.ts

export const userActions = {
    setProfileURL(url: string) {
        // ...
    } 
}

What I wonder most now is

  1. Pros and Cons of this approach / reasonable alternatives?
  2. Does this break some core functionality of Vuex?
  3. Is there even some functionality under the hood of Vuex that could be broken like some optimization/caching mechanisms (at least on the getter side)?
alexeis
  • 2,152
  • 4
  • 23
  • 30
  • 2
    This is a pretty broad question. And you can access one module's action from another module by using the `dispatch` method provided in the first parameter of all action functions: see https://stackoverflow.com/questions/42984132/is-there-a-way-to-dispatch-actions-between-two-namespaced-vuex-modules – thanksd Jan 28 '19 at 20:52
  • Having a single source of *"truth"* is probably the biggest advantage Vue has and its where it draws its awesomeness from (and it's what Angular got fundamentally wrong). Obviously, you can achieve the same in Angular, but most people get lost using the anti-pattern you're aiming for here. I don't want to sound aggressive (I'm coming from Angular myself), you do as you please, but I'm warning this might not be a direction worth pursuing. – tao Jan 28 '19 at 21:43
  • @thanksd You're right, I will consider this although I don't like the lack of type-safety and missing auto-complete functionality but I guess this goes into the same category like the Vuex decorators. Thanks! – alexeis Jan 29 '19 at 18:15
  • @AndreiGheorghiu I'm not sure I fully understood your answer; which parts exactly would I break by exporting custom functions to do the business logic and then use custom setters to take care of state changes instead of the Actions/Mutations setup from Vuex? Probably I miss something here (I'm still rather new to programming)... Do multiple instances exist in my approach while Vuex works with Singletons (or suchlike)? Sorry for my confusing questions but you know how hard it is to figure out what you don't know (about) yet... Coming back to my initial question: What functionality would break? – alexeis Jan 29 '19 at 18:19
  • 1
    I haven't answered, I commented. To dispatch another module's action you have to call `dispatch('otherModule/action', {actionParams}, {root: true})`. Same goes for committing another module's mutation. Is that what you are trying to do? – tao Jan 29 '19 at 18:35

0 Answers0