Nuxt.jsビギナーズガイド
posted with ヨメレバ
花谷拓磨 シーアンドアール研究所 2018年10月
Nuxt.jsの基本
pagesディレクトリ
- users/_id.vueは/users/100のようなURLでアクセスすることができる。
<template>
<h1>id: {{ $route.params.id }}</h1>
</template>
<!-- またはdataでuserId: this.$route.params.idとして -->
<template>
<h1>id: {{ userId }}</h1>
</template>
- /users/100/postsのようなURLにしたい場合はusers/_userId/posts.vueのようにディレクトリ名の先頭を_にする。
<!-- users/_userId/posts/_postId.vueに/users/100/posts/200でアクセスした場合 -->
<ul>
<li>userId: {{ $route.params.userId }}</li>
<li>postId: {{ $route.params.postId }}</li>
</ul>
<!-- ※ users/_userId/index.vueとusers/_userId.vueのようにディレクトリ名とファイル名が同じ_xxxxだとファイルの方が優先される。 -->
axios-module
- axiosにリクエストのフックなどの機能を追加したNuxt.js専用のライブラリ。
- https://axios.nuxtjs.org
使い方
1. npm install @nuxtjs/axios
2. nuxt.config.jsに追記
modules: ['@nuxtjs/axios'],
axios: {},
3. jsを記述
async asyncData({app}) {
const json = await app.$axios.$get('https://qiita.com/api/v2/items?query=tag=nuxt.js');
return { json };
},
asyncData()フック
- Vue.jsではAPIでデータを取得する処理はcreated()フックに書くのが一般的である。
しかし、created()フックはブラウザでの実行となるため、Nuxt.jsではcreated()でははなくasyncData()フックに書いてSSRにも対応させる。 - asyncData()フックはコンポーネントの初期化前に実行されるため、thisへのアクセスができない。
asyncData(context)
と引数を取得することでcontext.app
やcontext.params
を使うことができる。
通常は分割代入を使ってasyncData({app, params})
のように書く。 - https://negalog.com/nuxt-js-fetch-data/
- https://nuxtjs.org/ja/docs/internals-glossary/context/
head()によるHTMLメタの設定
- nuxt.config.jsのheadにtitleなどを設定する。
- titleTemplateを設定すると、共通のタイトルをsprintf記法で設定することができる。
head: {
title: 'my-first-nuxt-app',
titleTemplate: '%s | Nuxt.js Test',
// 以下省略
}
- 各ページでは以下のようにタイトルを指定する。
head() {
return {
title: 'nuxt.jsタグ一覧',
}
}
// headメソッドはnuxt.config.jsのheadの値をオーバーライド(差分のみ)する。
vuex
- Nuxt.jsアプリケーションは画面遷移やAPIキャッシュが必要になることが多いため、vuexを利用することをオススメする。
- Nuxt.jsでvuexを使う場合、クラシックモードとモジュールモードがある。
クラシックモード
- クラシックモードの場合、storeディレクトリにindex.jsを作成しVuex.Storeインスタンスを返却する関数を定義する。
- Nuxt.jsのv3ではVuexのクラシックモードが廃止されるため、モジュールモードを使うべき。
クラシックモードのサンプル
import Vuex from 'vuex';
export default () =>
new Vuex.Store({
state: {
articles: [],
},
mutations: {
setArticles(state, {articles}) {
state.articles = articles;
},
},
actions: {
setArticles({commit}, {articles}) {
commit('setArticles', {articles});
},
},
})
各コンポーネントからは、this.$store
でアクセスすることができる。
asyncDataフックでは以下のようになる。
asyncData({store}) {
store.dispatch('setArticles', {articles: [1, 2]});
console.log(store.state.articles);
}
モジュールモード
Nuxt.jsはstoreディレクトリ内のファイルに対して、以下のルールで動作する。
- index.jsはルートモジュールである。
- index.jsがStoreインスタンスをexportしている場合はクラシックモード、そうでない場合はモジュールモードとなる。
- index.js以外のjsファイルはファイル名のスコープによるモジュールとして扱われる
モジュールモードのサンプル
export const state = () => ({
isLoading: false
})
export const mutations = {
setIsLoading(state, isLoading) {
state.isLoading = isLoading
}
}
export const state = () => ({
list: []
})
export const mutations = {
addUser(state, user) {
state.list.push(user)
}
}
export const actions = {
addUser({ commit }, { user }) {
commit('addUser', user)
}
}
usersはモジュールとして扱われるため、gettersやactionsへのアクセスは以下のようになる。
store.dispatch('users/addUser', {user: 'hoge'});
console.log(store.state.users.list);
上記の例はクラシックモードで以下のようにindex.jsを記述した場合と同等に扱われる。
import Vuex from 'vuex';
export default () =>
new Vuex.Store({
state: {
isLoading: false
},
mutations: {
setIsLoading(state, isLoading) {
state.isLoading = isLoading
}
},
modules: {
users: {
state: {
list: [],
},
mutations: {
addUser(state, user) {
state.list.push(user)
},
actions: {
addUser({ commit }, { user }) {
commit('addUser', user)
},
},
},
},
})