You are browsing Nuxt 2 docs. Go to Nuxt 3 docs, or learn more about Nuxt 2 Long Term Support.

Translated page Contents of this page might be outdated.

O diretório store

O diretório store contém seus ficheiros de memória do Vuex. A memória do Vuex vem fora da caixa com o Nuxt mas está desativada por padrão. A criação de um ficheiro index.js dentro deste diretório ativa a memória.


Este diretório não pode ser renomeado sem configuração extra.

Usar uma memória para gerir o estado é importante para toda grande aplicação. Isto é o porquê do Nuxt implementar o Vuex dentro do seu núcleo.

Ativar a memória

O Nuxt irá procurar pelo diretório store. Se ele conter um ficheiro, que não seja um ficheiro oculto ou um ficheiro README.md, então a memória será ativada. Isto significa que o Nuxt irá:

  1. Importar o Vuex
  2. Adicionar a opção store à instância raíz do Vue.

Os módulos

Todo ficheiro .js dentro do diretório store é transformado em um módulo com nome reservado (com o index sendo a raiz do módulo). O seu valor de state sempre será uma function para evitar estado partilhado indesejado no lado do servidor.

Para começar, exporte o estado (state) como uma função, e as mutações (mutations) e ações (actions) como objetos.

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

export const mutations = {
  increment(state) {
    state.counter++
  }
}

Depois, você pode ter um ficheiro store/todos.js:

store/todos.js
export const state = () => ({
  list: []
})

export const mutations = {
  add(state, text) {
    state.list.push({
      text,
      done: false
    })
  },
  remove(state, { todo }) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle(state, todo) {
    todo.done = !todo.done
  }
}

A memória será criada tal e qual:

new Vuex.Store({
  state: () => ({
    counter: 0
  }),
  mutations: {
    increment(state) {
      state.counter++
    }
  },
  modules: {
    todos: {
      namespaced: true,
      state: () => ({
        list: []
      }),
      mutations: {
        add(state, { text }) {
          state.list.push({
            text,
            done: false
          })
        },
        remove(state, { todo }) {
          state.list.splice(state.list.indexOf(todo), 1)
        },
        toggle(state, { todo }) {
          todo.done = !todo.done
        }
      }
    }
  }
})

E dentro do seu pages/todos.vue, ao usar o módulo todos:

pages/todos.vue
<template>
  <ul>
    <li v-for="todo in todos" :key="todo.text">
      <input :checked="todo.done" @change="toggle(todo)" type="checkbox">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
    </li>
    <li><input @keyup.enter="addTodo" placeholder="What needs to be done?"></li>
  </ul>
</template>

<script>
import { mapMutations } from 'vuex'

export default {
  computed: {
    todos () {
      return this.$store.state.todos.list
    }
  },
  methods: {
    addTodo (e) {
      this.$store.commit('todos/add', e.target.value)
      e.target.value = ''
    },
    ...mapMutations({
      toggle: 'todos/toggle'
    })
  }
}
</script>

<style>
.done {
  text-decoration: line-through;
}
</style>

O método do módulo também funciona para definições de alto-nível sem a implementação de um sub-diretório dentro do diretório store.

Exemplo para estado (state): você cria um ficheiro store/state.js e adiciona o seguinte.

export default () => ({
  counter: 0
})

E os recuperadores (getters) podem estar no ficheiro store/getter.js:

store/getter.js
export default {
  getCounter(state) {
    return state.counter
  }
}

E as mutações (mutations) correspondentes podem estar no ficheiro store/mutations.js

store/mutations.js
export default {
  increment(state) {
    state.counter++
  }
}

E as ações (actions) correspondentes podem estar no ficheiro store/actions.js:

store/actions.js
export default {
  async fetchCounter({ state }) {
    // fazer requisição
    const response = { data: 10 };
    state.counter = response.data;
    return response.data;
  }
}

Exemplo de estrutura de pasta

Uma configuração complexa da estrutura de ficheiro/pasta memória pode parecer com isto:

 store/
--| index.js
--| ui.js
--| shop/
----| cart/
------| actions.js
------| getters.js
------| mutations.js
------| state.js
----| products/
------| mutations.js
------| state.js
------| itemsGroup1/
--------| state.js

Os plugins na memória

Você pode adicionar plugins adicionais à memória ao por eles dentro do ficheiro store/index.js:

store/index.js
import myPlugin from 'myPlugin'

export const plugins = [myPlugin]

export const state = () => ({
  counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

Mais informações sobre os plugins na: documentação do Vuex .

A ação nuxtServerInit

Se a ação nuxtServerInit estiver definida dentro da memória (store) e o modo estiver em universal, o Nuxt irá chamar ele com o contexto (apenas a partir do lado do servidor). É útil quando nós temos algum dado no servidor que nós queremos dar diretamente para o lado do cliente.

Por exemplo, vamos dizer que temos sessões no lado do servidor e podemos acessar o usuário conectado através do req.session.user. Para adicionar o usuário autenticado a nossa memória (store), nós atualizamos o nosso store/index.js para o seguinte:

store/index.js
actions: {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session.user) {
      commit('user', req.session.user)
    }
  }
}
Somente o módulo primário (dentro do store/index.js) será receber esta ação. Você precisará encadear as ações do módulo a partir de lá.

O contexto é dado ao nuxtServerInit como o segundo argumento dentro do método asyncData.

Se o nuxt generate for executado, o nuxtServerInit será executado para cada rota dinâmica gerada.

Ações do nuxtServerInit assíncronas devem retornar uma promessa (Promise) ou usar o async/await para permitir o servidor do nuxt esperar neles.
store/index.js
actions: {
  async nuxtServerInit({ dispatch }) {
    await dispatch('core/load')
  }
}

O modo estrito do Vuex

O modo estrito está ativado por padrão no modo de desenvolvimento e desativado no modo de produção. Para desativar o modo estrito em desenvolvimento, siga o exemplo abaixo dentro do store/index.js:

export const strict = false