ストアディレクトリ
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
Sébastien Chopin
Nazaré da Piedade
Nobu
川音리오
Maciek Palmowski
Nestor Vera
Daniel Roe
Yue Yang
Jeronimas
Clément Ollivier
Alexander Lichter
N3-rd
Adrien Zaganelli
Mag
Stefan Huber
Olga Bulat
Paiva
Florian Reuschel
Savas Vedova
HIJACK
Vinícius Alves
Kareem Dabbeet
Valentín Costa
Ryan Skinner
Alex Hirzel
Ajeet Chaulagain
René Eschke
Nico Devs
Muhammad
Naoki Hamada
Tom
Yann Aufray
Anthony Chu
Nuzhat Minhaz
Lucas Portet
Richard Schloss
Bobby
bpy
Antony Konstantinidis
Hibariya
Jose Seabra
Eze
Florian Lefebvre
Lucas Recoaro
Julien SEIXAS