ストアディレクトリ
store ディレクトリには Vuex ストアに関するファイルが含まれています。Vuex ストアは Nuxt に付属していてすぐに使えますが、デフォルトでは無効化されています。このディレクトリ内に index.js ファイルを作成することで、ストアが有効化されます。
ストアを使って状態を管理するのは、どういった大きなアプリケーションを作るにあたっても重要なことです。それがなぜ Nuxt がそのコアに Vuex を組み込んでいるかの理由です。
ストアを有効化する
Nuxt は store ディレクトリを確認します。もし隠しファイルや README.md ではないファイルが含まれていたら、ストアは有効化されます。これは Nuxt が以下を行うことを意味しています:
- Vuex をインポートする
-
ルートの Vue インスタンスに
storeオプションを追加します。
モジュール
store ディレクトリの中にあるすべての .js ファイルは名前空間付きモジュール に変換されます(index はルートモジュールになります)。state の値は不必要に状態がサーバサイドで共有されてしまうことを避けるため、常に function であるべきです。
はじめに、ステートを関数で、ミューテーションとアクションをオブジェクトでエクスポートしましょう。
export const state = () => ({
counter: 0
})
export const mutations = {
increment(state) {
state.counter++
}
}
次に、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
}
}
ストアは以下のように生成されるでしょう:
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
}
}
}
}
})
また、pages/todos.vue では todos モジュールを以下のように利用することができます:
<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>
モジュールメソッドはストアディレクトリにサブディレクトリを追加することなく、トップレベルでの定義に利用することができます。
ステートの例: 以下のように store/state.js を作成します。
export default () => ({
counter: 0
})
対応するミューテーションは store/mutations.js に置くことができます
export default {
increment(state) {
state.counter++
}
}
例のフォルダ構造
複雑なストア設定のファイル/フォルダ構造は次のようになります:
store/
--| index.js
--| ui.js
--| shop/
----| cart/
------| actions.js
------| getters.js
------| mutations.js
------| state.js
----| products/
------| mutations.js
------| state.js
------| itemsGroup1/
--------| state.js
ストアでのプラグイン
store/index.js ファイルの中に置くことで、ストアにプラグインを追加することができます:
import myPlugin from 'myPlugin'
export const plugins = [myPlugin]
export const state = () => ({
counter: 0
})
export const mutations = {
increment(state) {
state.counter++
}
}
プラグインについてより詳細な情報はこちら: Vuex のドキュメント
nuxtServerInit アクション
ストアに nuxtServerInit アクションが定義されていて、かつ universal モードの場合、Nuxt はコンテキストを渡してこれを呼び出します(サーバサイドのみ)。これはサーバにある何らかのデータを直接クライアントサイドに渡すときに便利です。
例えば、サーバサイドにセッションがあり、req.session.user で接続したユーザにアクセスできるとしましょう。認証されたユーザをストアに渡すには、store/index.js を以下のように変更します:
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
store/index.js 内の)プライマリモジュールだけです。ここから他のモジュールのアクションに呼び出しを繋いでいく必要があります。コンテキスト は asyncData メソッドのように、nuxtServerInit の第 2 引数として渡されます。
nuxt generate が走った場合、nuxtServerInit は全ての動的に生成されたルートで実行されます。
nuxtServerInit アクションは、Promise を返すか async/await を利用して nuxt サーバが待機できるようにしなければなりません。actions: {
async nuxtServerInit({ dispatch }) {
await dispatch('core/load')
}
}
Vuex 厳格モード
厳格モードは dev モードではデフォルトで有効になっていて、production モードでは無効になっています。 厳格モードを dev モードでも無効化するには、store/index.js を下記の例に従ってください:
export const strict = false
Clément Ollivier
Daniel Roe
Alex Hirzel
Ajeet Chaulagain
René Eschke
Sébastien Chopin
Nico Devs
Muhammad
Nazaré da Piedade
Naoki Hamada
Tom
Yann Aufray
Anthony Chu
Nuzhat Minhaz
Lucas Portet
Richard Schloss
Xanzhu
bpy
Antony Konstantinidis
Hibariya
Jose Seabra
Eze
Florian LEFEBVRE
Lucas
Julien SEIXAS
Hugo
Sylvain Marroufin
Spencer Cooley
Piotr Zatorski
Vladimir Semenov
Harry Allen
kazuya kawaguchi
Unai Mengual
Hyunseung Lee
Alexandre Chopin
pooya parsa
Nick Medrano
Mosaab Emam
Iljs Путлер Капут
Heitor Ramon Ribeiro
Nero
Yoon Han
Ikko Ashimine
FamCodings
Ayouli
F. Hinkelmann
felipesuri
Christophe Carvalho Vilas-Boas
Leoš Literák
Trizotti
Marcello Bachechi
Rodolphe
Thomas Underwood
Shek Evgeniy
Lukasz Formela
Hugo Torzuoli