Nuxt.js
API
方針を決める
Nuxt のプロダクション環境での使い方は 3 つある。
Universal Mode(サーバあり)
mode: 'universal'
- デプロイ方法 --- Node.js サーバにソースをクローンし
yarn start
する。サーバが必要。 - 非同期データは、
- 初回リクエスト時はサーバ側で取得する(常に最新)
- ページ遷移時など、2 回目以降はクライアント側で取得する
Universal Mode(サーバなし)
mode: 'universal'
- デプロイ方法 ---
nuxt generate
で生成された静的ファイルを単に配布する。サーバが不要。 - 非同期データは、
- 初回リクエスト時は、ビルド時に取得したデータで固定される(=疑似的な SSR と考えればよい)。このため、動的データに変更があったときは再ビルド・再デプロイが自動で行われるフローを構築するなどの処置が必要となる。
- ページ遷移時など、2 回目以降はクライアント側で取得する
SPA Mode
mode: 'spa'
- デプロイ方法 ---
nuxt generate
で生成された静的ファイルを単に配布する。サーバが不要。 - 非同期データは常にクライアント側で取得する
インストール
create-nuxt-app を使う
yarn global add create-nuxt-app
create-nuxt-app some-app
cd some-app
yarn dev
自前で作る
package.json
{
"name": "my-app",
"scripts": {
"dev": "nuxt"
},
"dependencies": {
"nuxt": "^2.0.0"
}
}
pages/index.vue
<template>
<h1>Hello world!</h1>
</template>
yarn
yarn dev
Directory Structure
Directories
assets
- webpack でコンパイルされるべき Less, Sass, Javascript ファイルなどを格納する
components
- Vue コンポーネントを格納する
- Nuxt.js は
components
ディレクトリ内のコンポーネントの data メソッド については手を加えない - 一方、Nuxt.js は
pages
ディレクトリ内のコンポーネントの data メソッドには非同期データを扱えるよう手を加える
layouts
- アプリケーションのレイアウトファイルを格納する。
middleware
- ミドルウェアを格納する
- ミドルウェアは、ページやレイアウトをレンダリングする前に動作するファンクションである。
pages
.vue
ファイルを格納する。ここに配置したファイルが、View と Routes になる。
plugins
- root Vue.js Application が動きはじめる前に動作させたいプラグインを格納する
static
- 静的ファイルを格納する。
- ここに置いたファイルは webpack を経由せず、そのまま
/
に配置される
store
- Vuex 関連のファイルを格納する
nuxt.config.js
- nuxt.js のコンフィグファイル
Aliases
~
or@
はsrcDir
を指す~~
or@@
はrootDir
を指す
デフォルトでは srcDir と rootDir は同じ
vue テンプレートでファイルを相対指定する時に、次のように使う
~/assets/your_image.png
~/static/your_image.png
Configuration
設定項目
build
- webpack 関連の設定を行う
- 例えば、webpack の
vendor.bundle.js
に入れ込むモジュールを指定する。これにより本体 bundle の容量を減らすことができる。
- 例えば、webpack の
css
グローバルに使用する CSS を指定する。
dev
development
or production
モードを指定する。
env
環境変数を指定する。環境変数はサーバサイド、クライアントサイドの両方から参照できる。
generate
nuxt generate
(Static Generated Deployment)した時、動的なルーティングは無視される。
動的なルーティングも含めて静的な HTML ファイルに変換したいときは、ここに設定を記述する。
head
デフォルトの meta タグを指定する
loading
ローディング中に表示するコンポーネントを指定する
modules
nuxt で使用するモジュールを指定する。モジュール= nuxt の設定を一括して行うプラグインのようなもの
modulesDir
node_modules
フォルダの場所を指定する。
yarn の workspaces 機能を使っているなら、下記の設定が必須。
// 例えば`<projectRoot>/packages/nuxt`にnuxtプロジェクトを格納している場合
modulesDir: ['../../node_modules'],
plugins
root Vue.js Application を開始する前に動作させたいプラグインを指定する。
rootDir
nuxt のルートディレクトリを指定する
server
ポート番号、IP、証明書の場所など、サーバのセットアップに関する情報を指定する。
router
vue-router の設定を指定する。
srcDir
ソースディレクトリを指定する。
transition
ページのトランジションを指定する。
Routing
Routes
- ファイル名が
index.vue
だと、パスは''
(ホーム)になる - フォルダ名 or ファイル名に
_
をつけると Dynamic Route(:id
など) になる - フォルダ内の
_
ファイルは一つまで。2 つ以上あると名前順で一番上のものが採用される - フォルダ内に
index.vue
が存在し ない場合、_
から始まるファイルは任意のDynamic Route になる(index.vue の役割を兼ねる) - Dynamic Routes は
nuxt generage
コマンドでは無視される
pages/
--| category/
-----| _id.vue
--| users/
-----| _id.vue
-----| index.vue
--| index.vue
routes = [
{
name: 'index',
path: '/',
component: 'pages/index.vue',
},
{
name: 'category-id',
path: '/category/:id?',
component: 'pages/category/_id.vue',
},
{
name: 'users',
path: '/users',
component: 'pages/users/index.vue',
},
{
name: 'users-id',
path: '/users/:id',
component: 'pages/users/_id.vue',
},
];
Nested Routes
- ネストした Routes を定義するには、フォルダ名と同名の vue ファイルを作成する
pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue
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',
},
],
},
];
Dynamic Nested Routes
Dynamic Routes をネストさせることもできる。
pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue
routes = [
{
path: '/',
component: 'pages/index.vue',
name: 'index',
},
{
path: '/:category',
component: 'pages/_category.vue',
children: [
{
path: '',
component: 'pages/_category/index.vue',
name: 'category',
},
{
path: ':subCategory',
component: 'pages/_category/_subCategory.vue',
children: [
{
path: '',
component: 'pages/_category/_subCategory/index.vue',
name: 'category-subCategory',
},
{
path: ':id',
component: 'pages/_category/_subCategory/_id.vue',
name: 'category-subCategory-id',
},
],
},
],
},
];
SPA fallback
TODO: よくわからない
Dynamic Routes で SPA フォールバックを有効にするには設定が必要らしい。ドキュメント参照。
リン クの貼り方、子コンポーネントの配置の仕方
<!-- リンクを貼る router-linkは使えない-->
<nuxt-link to="/">Home page</nuxt-link>
<!-- 子コンポーネントの配置 router-viewは使えない -->
<nuxt-child />
Vlidation
- params のバリデーションを行うには、コンポーネントで次のようにする。
- booblean か、boolean を解決する Promise を返すこと。
- false だった場合は 404 ページ又は 500 ページが表示される。
export default {
validate({ params }) {
// Must be a number
return /^\d+$/.test(params.id);
},
};
Transitions
グローバルセッティング
- Nuxt.js のデフォルトトランジション名は
page
である。 - トランジションの詳細については Vue.js のドキュメントを参照
/* assets/main.css */
.page-enter-active,
.page-leave-active {
transition: opacity 0.5s;
}
.page-enter,
.page-leave-to {
opacity: 0;
}
// nuxt.config.js
module.exports = {
css: ['assets/main.css'],
};
ページ単位のセッティング
/* assets/main.css */
.test-enter-active,
.test-leave-active {
transition: opacity 0.5s;
}
.test-enter,
.test-leave-active {
opacity: 0;
}
// コンポーネントで
export default {
transition: 'test',
};
Middleware
- ページ(又はページグループ)をレンダリングする前になにかの処理を行うためのもの。
middleware
フォルダに配置する- ファイル名がミドルウェア名になる
middleware/auth.js
=>auth
- ミドルウェアは非同期にすることもできる。非同期にしたい場合は Promise を Return すること。
ミドルウェアはcontext
を引数に取る。Context の詳細はこちら。context を書き換えたり、context にプロパティを追加することで、後にコンポーネントのasyncData
やfetch
で使えるようにする。
// middleware/auth.js
export default function (context) {
context.userAgent = context.isServer
? context.req.headers['user-agent']
: navigator.userAgent;
}
ミドルウェアは下記の順で実行される。
nuxt.config.js
- マッチしたレイアウト
- マッチしたページ
ミドルウェアを使用するときは、nuxt.config.js
、レイアウト、又はページに置いてmiddleware
キーを指定する。
// nuxt.config.jsの例
module.exports = {
router: {
middleware: 'auth',
},
};
Views
Document
ルートディレクトリにapp.html
を配置することでデフォルトの HTML テンプレートを上書きできる。
デフォルト設定は以下の通り。
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
Layouts
layouts/default.vue
を作成することで、デフォルトのレイアウトを上書きできる。
デフォルト設定は以下のとおり。
<template>
<nuxt />
</template>
レイアウトファイルは下記の 3 パターンで作るのが鉄板。
default.vue
(共通画面など。ヘッダ・フッタあり)home.vue
(トップページなど。全画面)blank.vue
(規約やお問い合わせ表示用の 1 カラム画面)
Error Page
layouts/error.vue
を作成することで、デフォルトのエラーページを上書きできる。
デフォルト設定はこちら
Custom Layout
layouts
フォルダの第一階層においたファイルは、レイアウトとして登録される。登録したレイアウトは、コンポーネントで使用することができる。
例)layouts/blog.vue
<template>
<div>
<div>My blog navigation bar here</div>
<nuxt />
</div>
</template>
コンポーネント側でレイアウトを指定する
export default {
layout: 'blog',
};
Pages
Nuxt のページは、全て Vue コンポーネントである。 Nuxt は、このコンポーネントに特別なキーを追加して、アプリケーションの開発を容易にする。
// コンポーネント
export default {
asyncData(context) {},
fetch() {},
head() {},
// and more functionality to discover
};
キー名 | 説明 |
---|---|
asyncData | ページがインスタンス化される前に、データを取得し、data にセットする。context を引数として受け取る。 |
fetch | ページがインスタンス化される前に、データを取得する。data にセットするのではなく、storeを操作する時に使う。context を引数として受け取る。 |
head | 現在のページに対して<meta> タグを設定する。 |
layout | layouts ディレクトリに定義されているレイアウトを指定する |
loading | loadingの状態を手動で処理する場合に使う。詳細はAPIドキュメントを参照。 |
transition | ページの特定のトランジションを設定する |
scrollToTop | Boolean型(デフォルト値:false)で、ページをレンダリングする前にページを一番上にスクロールするかどうかを指定する。これはネストされたルートに使用される。 |
validate | 動的なルーティングを行った際にparams を検証する |
middleware | このページのミドルウェアを設定する |
watchQuery | どのクエリが変更された時に、上記のメソッド群を実行するか指定する(デフォルトではクエリ変更時に上記のメソッド群は実行されない) |
HTML Head
nuxt は head の管理にvue-meta
を使用している。デフォルトの設定は以下の通り。
{
keyName: 'head', // the component option name that vue-meta looks for meta info on.
attribute: 'data-n-head', // the attribute name vue-meta adds to the tags it observes
ssrAttribute: 'data-n-head-ssr', // the attribute name that lets vue-meta know that meta info has already been server-rendered
tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag
}
アプリケーション単位、ページ単位で head プロパティを設定できる。
// グローバル設定(nuxt.config.js)の例
config = {
head: {
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
],
link: [
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css?family=Roboto',
},
],
},
};
// ローカル設定の場合
export default {
head() {
return {
script: [
{
src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js',
},
],
link: [
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css?family=Roboto',
},
],
};
},
};
親と子で重複させたくない項目については、hid
(本家ではvmid
と呼ばれている)キーを設定しておくことで子のほうが優先されるようになる。詳細はこちら。
Async Data
- return したオブジェクトが
data
にマージされる - Nuxt のモードにより、データ取得のタイミングが変わる
- Universal Mode: 初回はサーバで データ取得、以降はページ遷移時に Ajax で取得
- Pre Rendered Mode:
nuxt generate
時にデータを取得して、あらかじめ HTML 化 - SPA Mode: ページ遷移時に Ajax で取得
- 第一引数に
context
を受け取る - store は使えない
this
でコンポーネントインスタンスにアクセスすることはできない(Instanciate する前だから)
実装の方法は次の 3 種類がある。実装例はこちら。
- Promise を返す
- async/await を使う
- callback を使う
// async/awaitの例
export default {
async asyncData(context) {
let { data } = await axios.get(`https://my-api/posts/${context.params.id}`);
return { title: data.title };
},
};