関連:
- Vue.jsチートシート(基礎編)
- Vue.jsチートシート(コンポーネントと構成編)
Vueチートシートに引き続き公式チュートリアルの抜粋です。
参照
概要
Nuxt.js = Vue.jsおよびそのプラグインに基づくサーバサイドフレームワーク
- NuxtはVue.js, vue-router, vuex, Vue Server Render, Vue Metaなどを包含する
- Vueと同じく部分的に利用することができる(Progressive Framework)
公式によると以下のような機能を提供している:
- Vue ファイルで記述できること(*.vue)
- コードを自動的に分割すること
- サーバーサイドレンダリング
- 非同期データをハンドリングするパワフルなルーティング
- 静的ファイルの配信
- ES2015+ のトランスパイレーション
- JS と CSS のバンドル及びミニファイ化
- 要素(、 など)の管理
- 開発モードにおけるホットリローディング
- プリプロセッサ: Sass, Less, Stylus など
- HTTP/2 push headers ready
- モジュール構造で拡張できること
SSRの実現を主目的として導入されることが多いが、単純なSPAとして動作させることもできる
jekyllのようにVueコンポーネントから静的サイトをビルドすることもできる
Node.jsベースで動作する
- AppフレームワークとしてExpressをはじめとした複数を選択できる
- UIフレームワークも同様にBootstrap, Element UIなどを選択できる
- テストフレームワークも同様
導入
npxを使ってNuxtプロジェクトを簡単に作成できる
# npm5.2+はデフォルト$ npm install-g npx # インタラクティブに入力してプロジェクトを作成する# App/UI/テストフレームワークもここで選べる# yarn create nuxt-app <project-name> でも同じ$ npx create-nuxt-app <project-name> # 開発環境を起動$ npm run dev
既存のプロジェクトに導入する場合はnpmパッケージとしてインストールする
package.json// npm run devでnuxtが立ち上がるように設定しておく{"name":"my-app","scripts":{"dev":"nuxt"}}
$ npm install--save nuxt
基礎
ディレクトリ構造
Nuxtのプロジェクトは以下のようなディレクトリ構成をとる:
path | includes | memo |
---|---|---|
/assets/ | CSS(SASS), 画像, フォントファイルなど静的なファイル | |
/components/ | Vueコンポーネント | |
/layouts/ | アプリケーションレイアウト | |
/middleware/ | ミドルウェア(ページレンダリング以前に実行される処理) | |
/pages/ | ViewおよびRouter | これ以下のファイル構成をもとにしてRoutingを作成する |
/plugins/ | Vueのinstanciateより前に実行したい処理 | |
/static/ | サーバのroot直下に直接配置されるファイル | faviconやrobots.txtなど |
/store/ | Vuexストアファイル | |
/nuxt.config.js | Nuxtの設定 |
ディレクトリエイリアス
- Nuxt Appにおいて
~
あるいは@
はソースが格納されるディレクトリ(srcDir) を示す~~
,@@
はrootDir- srcDirとrootDirはデフォルトでは等値
設定の分類
/nuxt.config.js
の設定は以下のようなトップレベルのキー以下に分類される:
category | includes | memo |
---|---|---|
build | webpackを含むビルドオプション | |
css | 共有するCSSファイル/ライブラリの設定 | |
dev | Dev/Prodモード | |
env | 環境変数 | |
generate | routing | |
head | meta-tagの設定 | |
loading | ローディングコンポーネントの設定 | |
modules | Nuxtモジュールの設定 | |
modulesDir | node_modulesの所在 | |
plugins | plugins/ 以下の設定 | |
rootDir | Nuxtアプリケーションのroot | |
router | Vue Router設定 | |
server | サーバの設定 | |
srcDir | ソースの所在 | |
dir | カスタムディレクトリの設定 | |
transition | トランジションの設定 |
Routing
Nuxtはvue-routerを用いてページをルーティングする
ルーティングの自動生成
/pages/
内のファイル・ディレクトリ構造に基づいて、自動的に設定を生成するたとえばこんなファイル構成だとpages/ index.vue users/ index.vue
このようになるrouter:{routes:[{name:'index',path:'/',component:'pages/index.vue'},{name:'users',path:'/users',component:'pages/users/index.vue'},]}
Link
ページ間の遷移は
<router-link>
ではなく<nuxt-link>
を使う<nuxt-linkto="/">Home</nuxt-link>
パラメータ
URLにパラメータを含める場合はファイル名にアンダースコアをつける
pages/ users/ _id.vue posts/ _id/ index.vue
router:{routes:[// こうするとパラメータが必須でなくなる(?){name:'users-id',path:'/users/:id?',component:'pages/users/_id.vue'},// 必須にしたい場合はディレクトリを切る{name:'posts-id',path:'/posts/:id',component:'pages/posts/_id/index.vue'},]}
パラメータを検証することができる
- 検証失敗した場合、Nuxtサーバは404を返す
- あるいはエラーがthrowされた場合は500を返す
アンダースコアから始まる(パラメータを含む)ページの.vueファイルexportdefault{validate({params}){// 戻り地の真偽をもって検証の可否とするreturnparams.id>0}}
ネスト
ページをネストする場合は、リンクと同様に
<router-view>
ではなく<nuxt-child>
を親コンポーネントに配置するpages/ users/ _id.vue index.vue users.vue
// users.vueに <nuxt-child> を配置しておく必要があるrouter:{routes:[{path:'/users',component:'pages/users.vue',children:[{path:'',component:'pages/users/index.vue',name:'users'},{path:':id',component:'pages/users/_id.vue',name:'users-id'}]}]}
未知のパスをハンドルする
_.vue
ファイルを配置すると、その他にマッチしなかった全てをハンドルできる# / はindex.vue # /users/ はusers/ # /foo などそれ以外は _.vue pages/ _.vue index.vue users/
View
Appテンプレート
全てのViewに共通するHTML(Appテンプレート)を定義できる
- Appテンプレートは
/<rootDir>/app.html
として配置する
/app.html<!-- こんなふうに定義しておく(以下はNuxtのデフォルトのAppテンプレート --><!DOCTYPE html><html{{HTML_ATTRS}}><head{{HEAD_ATTRS}}> {{ HEAD }} </head><body{{BODY_ATTRS}}> {{ APP }} </body></html>
- Appテンプレートは
Layout
デフォルトのレイアウトは
/layouts/default.vue
である/layouts/default.vue<!-- nuxtタグにページがレンダリングされる --><template><nuxt/></template>
レイアウトをカスタムしたい場合は
/layouts
にファイルを配置する/layouts/custom.vue<template><!-- ...カスタムされたレイアウト --><nuxt/></template>
カスタムレイアウトはページ側で指定することで利用できる
exportdefault{layout:'custom'}
App内でエラーが発生した場合のエラーページは、レイアウトのひとつ(
error.vue
)として定義しカスタムできる- エラーページの例は 公開されている
ページ
Nuxt上のページ(Vueコンポーネント)は、SSRのために追加の機能が提供されている
page.vue<template><h1class="red">Hello {{name}}!</h1></template><script>exportdefault{// コンポーネントのロードの都度呼ばれる// 非同期で実行でき、戻り値はdataオブジェクトとマージされるasyncData(context){return...},// ページの描画前にstoreを初期化するfetch(){// ...},// <meta>を設定するhead(){// ...},// レイアウトを設定するlayout:'custom',// 遷移時のアニメーションを設定するloading:false,// 遷移時にスクロールを一番上に戻すかscrollToTop:true,// トランジションの設定//transition: ...,// ミドルウェアの設定//middleware: ...}</script><style>.red{color:red;}</style>
メタタグ
<meta>
の内容はすべてnuxt.config.js
に定義できる- ページ単位でカスタムしたい場合はコンポーネントにheadプロパティを定義する
nuxt.config.jshead:{meta:[{charset:'utf-8'},],link:[{rel:'stylesheet',href:'https://fonts.googleapis.com/css?family=Roboto'}]}
非同期データ処理
asyncDataとコンテキスト
コンポーネントの asyncData
プロパティ(メソッド)は、ページのロードとは非同期的なデータの読み込みのために用いる。
asyncDataが呼ばれるたびに、その結果がdataにマージされる
- サーバサイドでは、ページがリクエストされた際に一度だけ呼ばれる
- クライアントサイドでは、ページ遷移のたびに呼ばれる
asyncDataは
this
を使えない- コンポーネントがinstanciateされる前に、別のスコープで(非同期に)呼び出されるため
- 代わりに引数の
context
を介して必要なデータを取得できる
Promiseオブジェクトを返すほか、async/awaitを使って書くこともできる
// Promiseexportdefault{asyncData({params}){returnaxios.get('https://...').then((res)=>{return{...}})}}// async/awaitexportdefault{asyncasyncData({params}){let{data}=awaitaxios.get('...')return{title:data.title}}}
Promiseによってエラーの制御もできる
exportdefault{asyncData({params,error}){returnaxios.get('...').then((res)=>{return{...}}).catch((e)=>{error({statusCode:404,message:'Not Found'})})}}
Asset/Static
Asset
assets/
に配置されたファイルは vue-loader, file-loaderなどwebpackの機能を利用して「アセット」として参照できるアセットはvueファイルから、
~assets/...
の形式で参照できる<template><imgsrc="~/assets/image.png"></template>
file-loaderの場合、アセットファイルはサーバ上にバージョン付きのファイル名で配置される
url-loaderの場合、アセットファイル(画像)はURL-encodingされてHTML上にインライン展開される
Static
static/
に配置されたファイルは Assetの機能を利用することなく、単に静的なファイルとして配置・公開される- faviconなどはここに置く
Plugin
npmパッケージをNuxtで利用したい場合、インストールするだけでそのまま利用できる
$ npm install--save axios
<template> ... </template><script>importaxiosfrom'axios'exportdefault{asyncasyncData({params}){let{data}=awaitaxios.get('...')// ...}}</script>
Vueのプラグインを利用したい場合、
plugins/
以下に設定を追加する必要があるplugins/some-vue-plugin.jsimportVuefrom'vue'importSomeVuePluginfrom'some-vue-plugin'Vue.use(SomeVuePlugin)
nuxt.config.jsexportdefault{// ...plugins:['~/plugins/some-vue-plugin'// クライアント/サーバサイドにそれぞれ限定のプラグインはモードを指定できる{src:'~/plugins/some-client-only-plugin',mode:'client'}]// プラグインがES6などで書かれている場合はビルドの指定も必要になるbuild:{transpile:['some-vue-plugin']}}
Module
Module = Nuxt自体の機能拡張
- 例:
@nuxtjs/axios
: Nuxtとaxiosの統合@nuxtjs/auth
: 認証機能を提供する
- 例:
Moduleはnpmパッケージとして公開するほか、プロジェクトローカルに独自定義することもできる
modules/some-module.jsexportdefaultfunctionSomeModule(options){// ...}
ビルド/デプロイ
NuxtはCLIを提供しており、これによってビルドやデプロイができる
package.json{// ...// グローバルインストールした場合は $ nuxt で直接呼べる// ローカルインストールした状態で利用したい場合はpackage.jsonにscriptを設定する// $ npm run dev などとして利用可能"scripts":{"dev":"nuxt","build":"nuxt build","start":"nuxt start","generate":"nuxt generate","test":"jest"},}
Appの提供形式によって利用するコマンドが変わってくる
- 開発環境では
nuxt
でサーバを起動する - SSRの場合は
nuxt start
によって本番モードでサーバを起動する - 静的サイトの場合は
nuxt generate
でページをビルドする - SPAの場合も同様に
nuxt generate
でビルドする(SPAモード指定が必要)
- 開発環境では