简体   繁体   中英

Vuex with Nuxt Error: this.$store is undefined

I'm coding along with a Nuxt course and I got the following error while of course it worked in the tutorial.

TypeError: can't access property "dispatch", this.$store is undefined

store/index.js file:

import Vuex from "vuex";

const createStore = () => {
  return new Vuex.Store({
    state: { loadedPosts: [] },

    mutations: {
      setPosts(state, posts) {
        state.loadedPosts = posts;
      },
    },

    actions: {
      setPosts(vuexContext, posts) {
        vuexContext.commit("setPosts", posts);
      },
    },

    getters: {
      loadedPosts(state) {
        console.log("imhere");
        return state.loadedPosts;
      },
    },
  });
};

export default createStore;

the script in posts/index.vue file:

<script>
export default {
  data() {
    return {
      loadedPosts: [{id: "1",title: "First Post"}],
    };
  },

  created() {
    this.$store.dispatch("setPosts", this.loadedPosts);
  },
};
</script>

Firstly you don't have to import the vuex if you have a store/index.js. Nuxt will look for the store directory. If it contains a file, that isn't a hidden file or a README.md file, then the store will be activated. This means that Nuxt will:

  • Import Vuex.
  • Add the store option to the root Vue instance.

Now if for some reason the vuex and store were not imported (in case of when setting up the project you didn't put any .js file in /store) the $store will not be available. You can check it out in .nuxt/index.js folder if the store or vuex is imported or not. If not imported you can follow 4 ways to properly setup vuex in Nuxt.

Method 1: Root Namespace, One File

Let's start with the simplest store setup, a single file. If you create /store/index.js you can fill it with your state, mutations, actions and getters. With this setup there are no namespaces and everything lives in this single file.

// holds your root state
export const state = () => ({
  counter: 0
})

// contains your actions
export const actions = {
  counterUp({ state, commit }){
    commit('setCounter', state.counter + 1)
  }
}
// contains your mutations
export const mutations = {
  setCounter(state, value){
    state.counter = value
  }
}
// your root getters
export const getters = {
    myGetter(state){ return state.counter + 1000}
}

Method 2: Root Namespace, One File Per Intent

If your store code gets a little too big you can split up your store by intent! Just remove your index.js and create files for state, actions, mutations, and getters. Nuxt will automatically build them as one store in the root namespace. From the example above, we just need to move each section into its own file and use a default

export.
// /store/state.js
export default () => ({
  counter: 0
})

// /store/actions.js
export default {
  counterUp({ state, commit }){
      commit('setCounter', state.counter + 1)
  }
}

// /store/mutations.js
export default{
  setCounter(state, val){
      state.counter = val
  }
}
// /store/getters.js
export default {
  myGetter(state){ return state.counter + 1000}
}

Method 3: Namespaced, One File

If you'd like to use namespaces in your app, but still want a single file for a space, just name your single file the namespace you'd like it's contents under. If we take the index.js from Method 1 and name it cart.js, all of the getters, actions, mutations, and state would be under the cart namespace. To access a state within a namespace, just use a computed property with the namespace name after the state property.

computed:{
  counter(){
    return this.$store.state.cart.counter
  }
}

If you wanted to execute an action within a namespace, you would add the namespace + slash + action name.

this.$store.dispatch('cart/counterUp')

Method 4: Namespaced, One File Per Intent

As you might have guessed, you can also have a namespaced store with your intents split up too! If we take Method 2 and moved each file into a folder called cart it would look like this.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM