Home > OS >  How to show data from nuxt js store?
How to show data from nuxt js store?

Time:08-13

I new on Nuxt JS and try tutorial on nuxt website, i make store in store/index.js

export const state = () => ({
  mountain: [],
})

export const mutations = {
  addMountain(state, mountain) {
    state.mountain.push(mountain)
  },
}

export const actions = {
  async fetchMountain() {
    const mountain = await fetch("https://api.nuxtjs.dev/mountains").then(
      (res) => res.json()
    );
    // this.mountain = mountain
  }
}

after that i make page on pages/index.js

<template>
  <div>
    <h1>Nuxt Mountains</h1>
    <ul>
      <li v-for="mount of mountain">{{ mount.title }}</li>
    </ul>
    <button @click="$fetch">Refresh</button>
  </div>
</template>

<script>
import $store from "~/store";

export default {
  fetch() {
    return $store.state.mountain;
  },
};
</script>

but i dont see anyting? someone can help me

enter image description here

CodePudding user response:

This is how you can achieve this example.

/pages/index.vue

<template>
  <div>
    <h1>Nuxt Mountains</h1>
    <p v-show="$fetchState.pending">Loading mountains...</p>

    <ul v-show="!$fetchState.pending">
      <li v-for="mountain of mountains" :key="mountain.slug">
        {{ mountain.title }}
      </li>
    </ul>

    <hr />
    <button @click="$fetch">Refresh</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
  async fetch() {
    await this.fetchMountains()
  },
  computed: {
    ...mapState(['mountains']),
  },
  methods: {
    ...mapActions(['fetchMountains']),
  },
}
</script>

Few notes on above:

  • mapState and mapActions is not mandatory here, you could access them via $store.dispatch etc directly but it's IMO more clean and quite explicit/good practice
  • don't forget the :key on the v-for, it's mandatory
  • prefer to use async/await everywhere rather than a mix with .then

/store/index.js

export const state = () => ({
  mountains: [],
})

export const mutations = {
  SET_MOUNTAINS(state, mountains) {
    state.mountains = mountains
  },
}

export const actions = {
  async fetchMountains({ commit }) {
    const response = await fetch('https://api.nuxtjs.dev/mountains')
    const mountains = await response.json()
    commit('SET_MOUNTAINS', mountains)
  },
}

Few notes on above:

  • using UPPER_SNAKE_CASE is a nice convention for mutations
  • again, async await combo
  • mountains (plural) seems more appropriate because we will have several ones
  • calling the mutation after the HTTP call in the action is the usual way to go with Nuxt2

CodePudding user response:

the store object already exists within your context. so you don't need to import it at all ... example of how to use it:

 computed: {
     mountain () {
           return this.$store.state.mountain;
     }
  }

ps. why inside the computed? because we don't need the component to be rerendered every time an update happens to the module. only if the data you are accessing got updated that should trigger rerendering ...

but that is also not the best practice. you should always use modules.


to understand that better you should know that nuxt imports all the files inside the store folder automatically.

so every file you create inside the store file will be used as a new module in vuex store.

so for instance if you created a file called todo.js inside the store folder you will access it anywhere in the project using the following :

 computed: {
     mountain () {
           return this.$store.state.todo.mountain;
     }
  }

i would suggest you take a look into that from here : https://nuxtjs.org/docs/directory-structure/store/

  • Related