Search code examples
nuxt.jsvuex

Impossible call function from action module


being used to vuejs, I created a store on nuxt but impossible to succeed in calling a function coming from a module. from what I read, it is necessary that state is a function, thing that I made, but still not possible to call my function, here is how is my store:

store/index.js

import Vue from "vue";
import Vuex from "vuex";
import user from "./module/user";

Vue.use(Vuex);

export const store = new Vuex.Store({
    modules: {
        user,
    },
});

store/modules/user.js

import Vue from "vue"

export default {
    state = () => ({
        user: null
    }),
    getters: {
        getUser: (state) => state.user
    },
    mutations: {
        INIT_USER(state, data) {
            Vue.set(state, "user", data);
        }
    },
    actions: {
        async initUser({ commit }) {
            try {
                const user = "John"
                await commit("INIT_USER", user);
            } catch (err) {
                console.error(err);
            }
        }
    }
}

pages/profile.vue

<script>
import { mapActions } from "vuex";

export default {
    methods: {
        ...mapActions(["initUser"]),

        async getUser() {
            this.initUser();
        }
    }
}
</script>

I have exactly the same code on vuejs (except for the state which is a vuejs object) and it works, so I don't understand the difference with nuxt.

thank you for your help


Solution

  • Nuxt has its own way of handling Vuex modules, which you should definitely take advantage of. See https://nuxtjs.org/docs/directory-structure/store/

    Briefly, what you want to do is:

    • Under your store directory, create a file user.js and put your store code in it. Nuxt will pick it up automatically and register as a namespaced Vuex module.

    • Refactor your store code so it exports each piecce separately, like so:

        import Vue from "vue"
      
        export const state = () => ({
            user: null
        }),
        export const getters = {
            getUser: (state) => state.user
        },
        export const mutations = {
            INIT_USER(state, data) {
                Vue.set(state, "user", data);
            }
        },
        export const actions = {
            async initUser({ commit }) {
                try {
                    const user = "John"
                    await commit("INIT_USER", user);
                } catch (err) {
                    console.error(err);
                }
            }
        }
      
    • In your component - you can use the store as follows:

    
    import { mapActions } from "vuex";
    
    export default {
        methods: {
            ...mapActions('user', ['initUser']),
    
            async getUser() {
                this.initUser();
            }
        }
    }
    
    

    Or even like this:

    <script>
    export default {
        methods: {
            getUser() {
                this.$store.dispatch('user/initUser');
            }
        }
    }
    </script>