VeeValidate メモ

Vue のバリデーションライブラリ VeeValidate の使い方をまとめたもの。(VeeValidate 2.1.0-beta.11, Vue 2.5.17)

基本的な使い方

<input v-validate="'required|email'" type="email" name="email">
<span>{{ errors.first('email') }}</span>

バリデーションルールのシンタックス

<input v-validate="'required|min:6'" type="password" name="password">
<input v-validate="{ required: true, email: true }" type="email" name="email">

カスタムルール

// Function Form
Validator.extend('custom', (value, args) => {
  // Return a Boolean or a Promise that resolves to a boolean.
});

// Object Form
Validator.extend('custom', {
  getMessage(field, args) {
    // will be added to default locale messages.
    // Returns a message.
  },
  validate(value, args) {
    // Returns a Boolean or a Promise that resolves to a boolean.
  }
});
  • getMessage の引数 field はフィールド名 (String)
  • getMessage を利用すると現在のロケールの辞書に追加される。多言語対応をする場合は Localization API を利用する。

さらに詳しく

  • Custom Rules | VeeValidate
    • 引数を必要とするルール・他の入力フィールドと比較をするルール・Non-immediate なルール(immediate 修飾子が設定されていない場合、初期バリデーションをスキップする)・data プロパティについて、など

エラーメッセージ

エラーメッセージを変更/追加する

Validator.localize を利用して辞書 (rootDictionary) を登録する。

import { Validator } from 'vee-validate';

const dictionary = {
  en: {
    messages:{
      custom: () => 'Some English Message',
    }
  }
};
// Override and merge the dictionaries
Validator.localize(dictionary);

// メモ: メッセージを生成する関数の形式
// function rule (fieldName: string, params: any[], data?: any): string {
//   return `Some error message for the ${fieldName} field.`;
// }

Configuration | VeeValidate を利用して登録することも可。

入力フィールドの名前

エラーメッセージと同様に辞書を更新する。

const dictionary = {
  en: {
    attributes: {
      email: 'Email Address'
    }
  },
};

さらに詳しく

カスタムコンポーネントで使う

DEMO:

スコープ

f:id:ryotah:20181025225325p:plain

  • VeeValidate のバリデータスコープはコンポーネント毎につくられる
  • コンポーネントinject: ['$validator'] をすることで親のスコープを取得できる
  • メモリ消費量を抑えるため、バリデータスコープの自動生成をさせないことも可能方法
    • 設定変更に関しては Configuration | VeeValidate に詳細がある (inject: false)
    • (自動生成されなくなるので)自身のコンポーネントにバリデータスコープを生成したい場合は以下のように $_veeValidate を利用する
$_veeValidate: {
  validator: 'new'
}
  • 同じコンポーネント内(バリデータスコープ内)でフィールド名がコンフリクトする場合 data-vv-scope を利用してスコープを作成することができる(コンポーネント毎に生成されるバリデータスコープとは別物)
    • form タグに data-vv-scope を設定すると自動で入力フィールドにも同じスコープが設定される

DEMO:

参考:

  • Component Injections | VeeValidate
    • With SSR Frameworks like Nuxt, it is recommended to disable automatic injection since it may cause memory leaks due to all the validator instances being created for every component, which is not needed and may slow down your site.
  • Scopes | VeeValidate

VueI18n と一緒に使う

設定:

// ...
import en from '~/locales/en/validation';

Vue.use(VueI18n);

const i18n = new VueI18n();

Vue.use(VeeValidate, {
  // ...
  // i18nRootKey: 'validation', 'validation' is default
  i18n,
  dictionary: {
  en
  }
});

利用:

// 言語を変更する場合は `$i18n` から
this.$i18n.locale = 'ar';

言語ファイル:

import en from 'vee-validate/dist/locale/en';

// 最終的に VueI18n の言語データとして書き出される
export default {

  // VeeValidate の辞書形式
  attributes: {
    custom: 'Custom',
    // ...
  },
  messages: { 
    ...en.messages,
    custom: () => 'Some English Message',
  },
};

参考:

その他

Validator#validate と Validator#validateAll

validate に関しては Validator API | VeeValidate にまとまっているが validateAll に関しては情報が少ない。実際には、引数の形式は違うが機能としては同じものがいくつかある。validator.validateAll() より validator.validate() の方が実質の All だったりする。

// validate all fields.
validator.validate();

// validate a field that has a matching name with the provided selector.
validator.validate('field');

// validate a field within a scope.
validator.validate('scope.field');

// validate all fields within this scope.
// => 内部で validator.validateAll('scope') を呼ぶ
validator.validate('scope.*');

// validate all fields without a scope.
// => 内部で validator.validateAll() を呼ぶ
validator.validate('*');

DEMO:

Flags

DEMO:

export class Field {
  id: string;
  name: string;
  scope: string;
  flags: FieldFlags;
  isRequired: boolean;
  initial: boolean;
  el: any;
  value: any;
  rules: any;
  update(options:object): void;
}

export interface FieldFlags {
  untouched: boolean;
  touched: boolean;
  dirty: boolean;
  pristine: boolean;
  valid?: boolean;
  invalid?: boolean;
  validated: boolean;
  required: boolean;
  pending: boolean;
}

Validation Events

  • vee-validate はデフォルトで input イベントをリスニングしている
  • リスニング対象を変更したい場合、デフォルトの挙動を変更するか、フィールド毎に変更するか、2通りの方法がある
    • data-vv-validate-on

参考:

入力フィールドが動的に表示/生成される場合

Vue が要素を再利用しないように、ユニークな key を設定する必要がある。

参考:

Misc.

型定義ファイル

9月メモ・リンク集

9月に調べたことのメモです。

Vue 関連

ルーティング関連

i18n

言語データの整理方法メモ

{ 
  "common": { // 一般的な用語
     "action": {
       "close": "閉じる"
     },
     "label": {
       "calendar": "カレンダー"
     },
     // ...
  },
  "glossary": { // アプリケーション用語, Domain
    "task": {
      "label": {
        // ...
      },
    },
  },
  "components": { // Shared Components に対応
    "calendar": {
      // ...
    },
  },
  "modules": { // 各ルートに対応
    "todo": {
      // ...
    },
    "todos": {
      // ...
    }  
  },
}
  • Angular アプリでの例
  • 意味のグループと場所のグループ
    • common, glossary => 意味
    • components, modules => 場所 (View と強く結びつく)
  • common, glossary はどこの View からも呼び出しが可能。
    エイリアスが利用できるなら componentsmodules などから利用することも可。
  • 考慮したいこと
    • 翻訳依頼するときに翻訳者がコンテキストを理解しやすいか
    • 開発時に不要なメッセージが増えにくいか
      • 必要な言語を探しやすいか
      • 新しいメッセージをどこに追加するか迷わないか
    • 利用していないメッセージを発見しやすいか

その他

Vue.js vue-router Nuxt.js の各フック (など) がいつ実行されるかメモ

続編のようなものを書きました。 ryotah.hatenablog.com


GitHub - ryotah/vue-vue-router-nuxt-hooks

f:id:ryotah:20180924173906p:plain

ログに表示される内容:

  • [INFO] vue: [page] / [hook]
    • Vue.js のライフサイクルフック
    • created, beforeUpdate, destroyed, etc.
  • [INFO] vue-router: [page] / [guard]
    • vue-router のナビゲーションガード
    • beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave
  • [INFO] nuxt: [page] / [method]
    • Nuxt.js の asyncData, fetch

確認できること:

  • 以下の遷移
    • /hooks/parents/1
    • /hooks/parents/2
    • /hooks/parents/1/child
    • /hooks/parents/2/child
    • /hooks/parents/2/child?q=query
  • リダイレクトや遷移失敗 (abort) 時の処理
  • asyncData / fetch でページ (state) を初期化、beforeRouteLeave でページ (state) をリセットした場合の問題点の把握
    • 今回のモチベーションはこれ

8月メモ・リンク集

8月に調べたことのメモです。

Vue 関連

基礎

ちょっと応用

Angular 関連

JavaScript その他

その他

ISO 形式 (ISO 8601) の文字列判定

ISO 8601 - Wikipedia

ISO 8601は日付と時刻の表記に関する国際規格。

// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString

new Date().toISOString()
// => "2018-08-31T04:56:23.130Z"
const ISO8601_DATE_REGEX = /^\d{4}-?\d\d-?\d\d(?:T\d\d(?::?\d\d(?::?\d\d(?:\.\d+)?)?)?(?:Z|[+-]\d\d:?\d\d)?)?$/;

ISO8601_DATE_REGEX.test('20101010');
// => true
ISO8601_DATE_REGEX.test('2010-10-10');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00:00');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00:00:00');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00:00:00.000');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00:00:00.000Z');
// => true
ISO8601_DATE_REGEX.test('2010-10-10T00:00:00.000+09:00');
// => true

ISO8601_DATE_REGEX.test('2010-1-10');
// => false
ISO8601_DATE_REGEX.test('2010-10-10T');
// => false
ISO8601_DATE_REGEX.test('2010-10-10T00:00:00000');
// => false

Vue のリアクティブシステム

勉強会で発表した資料です。
Vue のリアクティブシステム、その中でも依存関係のある関数の収集と再実行をどのように実現しているのかについて解説しています。Object.defineProperty, Dep Class and Watcher.

--- # 話すこと - Vue のリアクティブシステムの一部を説明 - リアクティブシステム
=> モデルの変更がDOMに反映される仕組み --- ![inline](model-dom.png) https://blog.thoughtram.io//angular/2016/02/22/angular-2-change-detection-explained.html --- ![inline](data.png) [リアクティブの探求 — Vue.js](https://jp.vuejs.org/v2/guide/reactivity.html) --- # 一旦サンプルを --- **値段**と**数**から**合計金額**を表示するアプリケーション
<!-- html -->
<div id="app">
  <div>price: {{ price }}</div>
  <div>quantity: {{ quantity }}</div>
  <div>total: {{ total }}</div>
</div>
// js
const app = new Vue({
  el: '#app',
  data: {
    price: 100,
    quantity: 2
  },
  computed: {
    total() { return this.price * this.quantity; }
  }
});
https://stackblitz.com/edit/vue-reactivity(https://stackblitz.com/edit/vue-reactivity) --- - `data` - Vue インスタンスのためのデータオブジェクト - Vue インスタンスが作成されるとリアクティブシステムに追加される - `computed` - Vue インスタンスに組み込まれる算出プロパティ - 算出プロパティは依存関係にもとづきキャッシュされる --- # 今日のゴールは ---
let data = { price: 100, quantity: 2 };
let total = data.price * data.quantity;

console.log(total);
// => 200

data.quantity = 3;
console.log(total);
// => 300 ?
--- # その1 ## 関数を保存 ---
let data = { price: 100, quantity: 2 };

// 再計算できるように関数を保存
let target = 
  () => data.total = data.price * data.quantity;

target();
console.log(data.total);
// => 200

data.quantity = 3;
target();
console.log(data.total);
// => 300

// https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-96.js
--- - 保存される関数は複数必要 - 依存関係のある関数だけを管理したい --- # その2 ## Dependency Class ---
export let target = null;
export class Dep {
  constructor() {
    this.subscribers= [];
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      this.subscribers.push(target);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub());
  }
}
---
let data = { price: 100, quantity: 2 };
let watcher = 
  () => data.total = data.price * data.quantity;

const dep = new Dep();

target = watcher;
dep.depend();

target();
target = null;

console.log(data.total);
// => 200

data.quantity = 3;
dep.notify();
console.log(data.total);
// => 300

// https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-97.js
--- # Dependency Class の役割 --- ![inline](dep.png) https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d(https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d) --- ![inline](dep-2.png) https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d(https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d) --- ![inline](dep-3.png) https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d(https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d) --- - プロパティごとに `Dep` インスタンスが必要 - 依存関係のある関数だけを管理したい - (未解決) --- # その3 ## `Object.defineProperty` ---
Object.keys(data).forEach(key => {
  let _value = data[key];
  Object.defineProperty(data, key, {
    get() {
      console.log('get', key, _value);
      return _value;
    },
    set(value) {
      console.log('set', key, _value);
      _value = value;
    }
  });
});
---
Object.keys(data).forEach(key => {
  let _value = data[key];
  const dep = new Dep();
  Object.defineProperty(data, key, {
    get() {
      dep.depend();
      return _value;
    },
    set(value) {
      _value = value;
      dep.notify();
    }
  });
});

// ...

target = watcher;
target();
target = null;
--- # 完成
console.log(data.total);
// => 200

data.quantity = 3;
console.log(data.total);
// => 300
https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-99.js(https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-99.js) --- ![inline](data_with_annotations.png) https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d(https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d) --- # 振り返り - Vue のリアクティブシステムの一部を説明 - `Object.defineProperty` - `Dep` class - `Watcher` --- # 参考資料 - [The Best Explanation of JavaScript Reactivity 🎆 – Vue Mastery – Medium](https://medium.com/vue-mastery/the-best-explanation-of-javascript-reactivity-fea6112dd80d) --- # ご静聴ありがとうございました --- # おまけ1 ## Angular の場合 ---
export class AppComponent  {
  price: number;
  quantity: number;
  constructor() {
    this.price = 100;
    this.quantity = 2;
    (window as any).app = this;
  }
  get total() {
    return this.price * this.quantity;
  }
}

// コンソールから実行
window.app.quantity = 10;
// => DOMは更新されない
// => ボタンクリックなどをすると反映される
https://stackblitz.com/edit/vue-reactivity-case-of-angular(https://stackblitz.com/edit/vue-reactivity-case-of-angular) --- Angular のレンダリングに興味がある方は [日本語訳 Angular 2 Change Detection Explained | ](https://blog.lacolaco.net/post/translation-angular-2-change-detection-explained/) がおすすめです --- # おまけ2 ## Vue インスタンス作成時の実際のコードを追ってみる --- **instance/index** - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/index.js#L8(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/index.js#L8) `function Vue (options) {` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/index.js#L14(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/index.js#L14) `this._init(options)` --- **instance/init** - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/init.js#L16(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/init.js#L16) `Vue.prototype._init = function (options?: Object) {` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/init.js#L57(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/init.js#L57) `initState(vm)` --- **instance/state** - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L48(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L48) `export function initState (vm: Component) {` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L54(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L54) `initData(vm)` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L112(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L112) `function initData (vm: Component) {` --- - https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L151(https://github.com/vuejs/vue/blob/v2.5.17/src/core/instance/state.js#L151) `observe(data, true /* asRootData */)` --- **observer/index** - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js) `export function observe (value: any, asRootData: ?boolean): Observer | void {` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L123(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L123) `ob = new Observer(value)` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L37(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L37) `export class Observer {` --- - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L66(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L66) `defineReactive(obj, keys[i])` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L134(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L134) `export function defineReactive (` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L156(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L156) ` Object.defineProperty(obj, key, {` --- - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L162(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L162) `dep.depend()` - https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L188(https://github.com/vuejs/vue/blob/v2.5.17/src/core/observer/index.js#L188) `dep.notify()`

Nuxt.js 学習メモ(公式ドキュメントの雑な抜粋)

これは何か

Nuxt.js の公式ドキュメントを読んだときのメモです。
気になったところ、後でもう一度確認が必要そうなもの、など。
Nuxt.js のバージョンは v1.4.2。

Nuxt.js ガイド

プロローグ

f:id:ryotah:20180825174314p:plain

  • サーバーサイドレンダリング
    • nuxt コマンドを実行すると開発サーバーが起動されます。このサーバーはホットリローディング及び vue-server-render を備えており、vue-server-render は自動的にアプリケーションをサーバーサイドレンダリングするよう設定されています。

  • nuxt --spa
  • 静的ファイルの生成
    • (必要になったら読む)

はじめる

インストール

ディレクトリ構造

設定

  • nuxt.config.js
  • (必要になったら読む)

ルーティング

  • Nuxt.js は pages ディレクトリ内の Vue ファイルの木構造に沿って、自動的に vue-router の設定を生成します。

  • 動的なルーティング
    • users/_id.vue => /users/:id?, _slug => path: '/:slug',
    • user-id と名付けられたルートに :id? というパスがありますが、これはこの :id が必須ではないことを表します。もし必須にしたい場合は users/_id ディレクトリ内に index.vue ファイルを作成してください。

    • ルーティングのパラメータのバリデーション
<script>
  export default {
    validate ({ params }) {
      // 数値でなければならない
      return /^\d+$/.test(params.id)
    }
  }
</script>

ビュー

  • ドキュメント
    • HTML テンプレートを拡張するために、プロジェクトのルートディレクトリに app.html を作成します。

  • レイアウト
    • デフォルトレイアウト
      • layouts/default.vue ファイルを追加することでメインレイアウトを拡張できます。

      • 必ず コンポーネントを入れておくことを覚えておいてください。

    • エラーページ
      • layouts/error.vue ファイルを追加することでエラーページをカスタマイズできます。

      • <nuxt/> を含めてはならない

    • カスタムレイアウト
      • layouts ディレクトリの 第一階層 のファイルで、ページコンポーネント内の layout プロパティで指定できるカスタムレイアウトを作成できます。

      • pages/posts.vue ファイル内で、カスタムレイアウトを使うことを Nuxt.js に伝えます:

  • ページ
    • asyncData, fetch, head, layout, transition, scrollToTop, validate, middleware
  • HTML ヘッド
    • Nuxt.js は headers とアプリケーションの html attributes を更新するために vue-meta を使用しています。Nuxt.js はこれらのオプションで vue-meta を設定します:

    • Nuxt.jsでは、nuxt.config.js 内にデフォルトの タグを全て定義することができます。

非同期なデータ

  • Nuxt.js はコンポーネントのデータをセットする前に非同期の処理を行えるようにするために asyncData メソッドを追加しています。

  • asyncData メソッド
    • promise, async/await, callback のどれか
    • asyncData の結果はコンポーネントのデータと マージされ ます

  • コンテキスト
    • context 内で利用できるキーの一覧
    • 動的なルートデータへのアクセス
      • たとえば、動的ルートパラメータには、コンテキストオブジェクトを構成したファイルまたはフォルダの名前を使用してアクセスできます。 したがって、_slug.vue という名前のファイルを定義する場合、context.params.slug を介してアクセスできます。

    • クエリの変化のリスニング
      • デフォルトでは、クエリストリングの変化で asyncData メソッドは呼ばれません。ページネーションコンポーネントのビルド時などにこの振る舞いを変更したい場合は、ページコンポーネントの watchQuery プロパティを見るパラメータを設定することができます。

      • watchQuery プロパティ
  • エラー処理
    • Nuxt.js は、context に error (パラメータ)メソッドを追加し、エラーページを表示するためにそれを呼び出すことができます。

    • params.statusCode は、サーバーサイドから適切なステータスコードを表示するためにも使用されます。

    • callback({ statusCode: 404, message: 'ページが見つかりません' })
      • 第一引数を利用する

アセット

  • Webpack で取り扱う
    • デフォルトでは vue-loader は css-loader および vue-template-compiler を用いて、スタイルやテンプレートファイルを処理します。このコンパイル処理の中で、<img src="...">background: url(...)CSS @import などのすべての URL はモジュールの依存関係のように解決されます。

  • Webpack で扱わない静的ファイル

プラグイン

  • Nuxt.js では js プラグインを定義することができ、それはルートの Vue.js アプリケーションがインスタンス化される前に実行されます。

  • 外部パッケージの利用
    • こうすれば、バンドルファイルが膨れ上がることなく、どの場所にも import axios と書くことができます。

module.exports = {
  build: {
    vendor: ['axios']
  }
}

モジュール

  • モジュールは、Nuxt 起動時に順番に呼び出される、シンプルな関数です

  • Webpack の Tapable に基づいた Nuxt のモジュール設計のおかげで、モジュールは例えばビルドの初期化のような特定のエントリーポイントに、フックを簡単に登録できるのです。

  • 基本的なモジュールを書く
  • 非同期モジュール
  • 共通のスニペット
    • (後で読む)
  • 特定のフックでタスクを実行する
    • 単に Nuxt の初期化処理時だけではなく、特定の条件下でのみ、モジュールにある処理を実行させたいこともあるでしょう。

Vuex ストア

  • Nuxt.js は store ディレクトリを探索し存在するときには以下を実行します: 1. Vuex をインポートします 2. vuex モジュールを vendor のバンドルファイルに追加します 3. store オプションをルートの Vue インスタンスに追加し

  • クラシックモード
    • ストアをクラシックモードで有効にするには store/index.js ファイルを作成し、ストアインスタンスをエクスポートします:

  • モジュールモード
    • このオプションを使いたいときは、ストアインスタンスの代わりに、store/index.js 内でステート、ミューテーション、アクションをエクスポートします:

  • fetch メソッドは、ページがレンダリングされる前に、データをストアに入れるために使われます。

  • nuxtServerInit アクション
    • nuxtServerInit というアクションがストア内に定義されているときは、Nuxt.js はそれをコンテキストとともに呼び出します(ただしサーバーサイドに限ります)。サーバーサイドからクライアントサイドに直接渡したいデータがあるときに便利です。

    • コンテキストは、asyncDataや fetch メソッドと同様に nuxtServerInit に第二引数として渡されます。

  • Vuex Strict モード
    • Strict モードは dev モードではデフォルトで有効化されており、production モードでは無効化されています。strict モードを dev で無効化するには、以下の例を参照してください。

コマンド

  • コマンド一覧
    • nuxt
      • 開発サーバー起動
    • nuxt build
      • Webpack でビルド、ミニファイ
    • nuxt start
      • プロダクションモードでサーバーを起動(nuxt build 後に実行)
    • nuxt generate
  • プロダクションのデプロイ
    • Nuxt.js では 3つのモードからアプリケーションのデプロイを選択できます。サーバレンダリング、SPA、そして静的生成です。

    • (必要になったら読む)

開発ツール

  • エンドツーエンドテスト
    • (必要になったら読む)
  • ESLint と Prettier
    • (必要になったら読む)

その他