Sobes.tech
Middle

How to organize interaction with Vuex in a Vue.js application?

sobes.tech AI

Answer from AI

The following main approaches are used for interacting with Vuex in a Vue.js application:

  1. Getting State (Getters): Used to obtain derived state (computed properties) from the store.

    // in component
    import { mapGetters } from 'vuex';
    
    export default {
      computed: {
        // map store getter to local computed property
        ...mapGetters([
          'doneTodosCount',
          'getTodoById'
        ])
        // or map to a different name
        // ...mapGetters({
        //   // map this.localName to this.$store.getters.getterName
        //   localTodosCount: 'doneTodosCount'
        // })
      },
        methods: {
           // using getter with arguments
           getSpecificTodo(id) {
              return this.getTodoById(id); // Access getter as property or method
           }
        }
    }
    
  2. Getting State (State): Direct access to the store's state.

    // in component
    import { mapState } from 'vuex';
    
    export default {
      computed: {
        // map store state property to local computed property
        ...mapState([
          'count'
        ])
        // or map to a different name
        // ...mapState({
        //   // map this.localCount to this.$store.state.count
        //   localCount: 'count'
        // })
      }
    }
    
  3. Changing State (Mutations): The only way to change the store's state. Must be synchronous.

    // in component
    import { mapMutations } from 'vuex';
    
    export default {
      methods: {
        // map store mutation to local method
        ...mapMutations([
          'increment' // map this.increment() to this.$store.commit('increment')
        ])
        // or map to a different name
        // ...mapMutations({
        //   add: 'increment' // map this.add() to this.$store.commit('increment')
        // })
      },
        // call mutation
        someMethod() {
           this.increment(); // Or this.add();
        }
    }
    
  4. Asynchronous Operations (Actions): Used for async operations and calling mutations.

    // in component
    import { mapActions } from 'vuex';
    
    export default {
      methods: {
        // map store action to local method
        ...mapActions([
          'incrementAsync' // map this.incrementAsync() to this.$store.dispatch('incrementAsync')
        ])
        // or map to a different name
        // ...mapActions({
        //   addAsync: 'incrementAsync' // map this.addAsync() to this.$store.dispatch('incrementAsync')
        // })
      },
        // call action
        someMethod() {
            this.incrementAsync(); // Or this.addAsync();
        }
    }
    
  5. Modules: Dividing the store into modules for better organization of large applications.

    // Example module structure
    // store/index.js
    import Vue from 'vue';
    import Vuex from 'vuex';
    import moduleA from './modules/moduleA';
    import moduleB from './modules/moduleB';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    });
    
    // store/modules/moduleA.js
    const moduleA = {
      namespaced: true, // Enable namespace
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++;
        }
      },
      actions: {
        incrementIfOdd ({ state, commit }) {
          if ((state.count + 1) % 2 === 0) {
            commit('increment');
          }
        }
      },
      getters: {
        doubleCount (state) {
          return state.count * 2;
        }
      }
    };
    
    export default moduleA;
    

    Accessing module elements in a component is done through the namespace:

    // in component
    import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
    
    export default {
      computed: {
        ...mapState('a', [ // Access state of module 'a'
          'count'
        ]),
        ...mapGetters('a', [ // Access getters of module 'a'
          'doubleCount'
        ])
      },
      methods: {
        ...mapMutations('a', [ // Access mutations of module 'a'
          'increment'
        ]),
        ...mapActions('a', [ // Access actions of module 'a'
          'incrementIfOdd'
        ])
      }
    }