浏览代码

Merge pull request #30 from kazupon/translation

Translation for japanese
Evan You 9 年之前
父节点
当前提交
4a81e656d6
共有 19 个文件被更改,包括 971 次插入0 次删除
  1. 1 0
      docs/LANGS.md
  2. 1 0
      docs/ja/README.md
  3. 15 0
      docs/ja/SUMMARY.md
  4. 137 0
      docs/ja/actions.md
  5. 93 0
      docs/ja/api.md
  6. 1 0
      docs/ja/book.json
  7. 31 0
      docs/ja/concepts.md
  8. 92 0
      docs/ja/data-flow.md
  9. 36 0
      docs/ja/forms.md
  10. 29 0
      docs/ja/hot-reload.md
  11. 13 0
      docs/ja/intro.md
  12. 81 0
      docs/ja/middlewares.md
  13. 95 0
      docs/ja/mutations.md
  14. 2 0
      docs/ja/quickstart.md
  15. 51 0
      docs/ja/state.md
  16. 25 0
      docs/ja/strict.md
  17. 133 0
      docs/ja/structure.md
  18. 135 0
      docs/ja/testing.md
  19. 二进制
      docs/ja/vuex.png

+ 1 - 0
docs/LANGS.md

@@ -1,2 +1,3 @@
 * [English](en/)
 * [简体中文](zh-cn/)
+* [日本語](ja/)

+ 1 - 0
docs/ja/README.md

@@ -0,0 +1 @@
+SUMMARY.md

+ 15 - 0
docs/ja/SUMMARY.md

@@ -0,0 +1,15 @@
+# Table of Contents
+
+- [Vuex は何ですか?](intro.md)
+- [中核概念](concepts.md)
+  - [ステート](state.md)
+  - [ミューテーション](mutations.md)
+  - [アクション](actions.md)
+- [データフロー](data-flow.md)
+- [アプリケーションの構造](structure.md)
+- [ミドルウェア](middlewares.md)
+- [厳格モード](strict.md)
+- [フォームのハンドリング](forms.md)
+- [テスト](testing.md)
+- [ホットリローディング](hot-reload.md)
+- [API リファレンス](api.md)

+ 137 - 0
docs/ja/actions.md

@@ -0,0 +1,137 @@
+# アクション
+
+アクションはミューテーションをディスパッチする機能です。アクションは非同期にすることができ、単一アクションは複数のミューテーションをディスパッチできます。
+
+アクションは何かが起こるための意向を表しており、それを呼び出すコンポーネントから離れて詳細を抽象化します。コンポーネントが何かしたい場合アクション呼び出します。アクションはステート変化をもたらすため、コールバックまたは戻り値について心配する必要はなく、そしてステート変化は更新するコンポーネントの DOM をトリガします。コンポーネントは、アクションが実際に行われている方法から、完全に切り離されます。
+
+それゆえ、通常アクション内部のデータエンドポイントへの API 呼び出しを行い、そしてアクションを呼び出すコンポーネントの両方から非同期に詳細を隠し、さらにミューテーションはアクションによってトリガされます。
+
+> Vuex のアクションは純粋な Flux の定義では実際には "アクションクリエータ (action creators)" ですが、私はその用語は便利よりも混乱していると見ています。
+
+### 単純なアクション
+
+アクションは単純に単一のミューテーションをトリガするのが一般的です。Vuex はそのようなアクションの定義するために省略記法を提供します:
+
+``` js
+const store = new Vuex.Store({
+  state: {
+    count: 1
+  },
+  mutations: {
+    INCREMENT (state, x) {
+      state.count += x
+    }
+  },
+  actions: {
+    // 省略記法
+    // ミューテーション名を提供する
+    increment: 'INCREMENT'
+  }
+})
+```
+
+今、アクションを呼び出すとき:
+
+``` js
+store.actions.increment(1)
+```
+
+単純に私たちに対して以下を呼び出します:
+
+``` js
+store.dispatch('INCREMENT', 1)
+```
+
+アクションに渡される任意の引数は、ミューテーションハンドラに渡されることに注意してください。
+
+### 標準なアクション
+
+現在のステートに依存しているロジック、または非同期な操作を必要とするアクションについては、それらを関数として定義します。アクション関数は常に第1引数として呼び出す store を取得します:
+
+``` js
+const vuex = new Vuex({
+  state: {
+    count: 1
+  },
+  mutations: {
+    INCREMENT (state, x) {
+      state += x
+    }
+  },
+  actions: {
+    incrementIfOdd: (store, x) => {
+      if ((store.state.count + 1) % 2 === 0) {
+        store.dispatch('INCREMENT', x)
+      }
+    }
+  }
+})
+```
+
+
+関数本体それほど冗長にしない ES6 の argument destructuring を使用するのが一般的です(ここでは、`dispatch` 関数は store インスタンスに事前にバインドされているように、それをメソッドとして呼び出す必要はありません):
+
+``` js
+// ...
+actions: {
+  incrementIfOdd: ({ dispatch, state }, x) => {
+    if ((state.count + 1) % 2 === 0) {
+      dispatch('INCREMENT', x)
+    }
+  }
+}
+```
+
+以下のように、文字列省略記法は基本的に糖衣構文 (syntax sugar) です:
+
+``` js
+actions: {
+  increment: 'INCREMENT'
+}
+// 以下に相当 ... :
+actions: {
+  increment: ({ dispatch }, ...payload) => {
+    dispatch('INCREMENT', ...payload)
+  }
+}
+```
+
+### 非同期なアクション
+
+非同期なアクションの定義に対して同じ構文を使用することができます:
+
+``` js
+// ...
+actions: {
+  incrementAsync: ({ dispatch }, x) => {
+    setTimeout(() => {
+      dispatch('INCREMENT', x)
+    }, 1000)
+  }
+}
+```
+
+より実践的な例はショッピングカートをチェックアウトする場合です。複数のミューテーションをトリガする必要がある場合があります。チェックアウトを開始されたとき、成功、そして失敗の例を示します:
+
+``` js
+// ...
+actions: {
+  checkout: ({ dispatch, state }, products) => {
+    // カートアイテムで現在のアイテムを保存する
+    const savedCartItems = [...state.cart.added]
+    // チェックアウトリクエストを送り出し、
+    // 楽観的にカートをクリアします
+    dispatch(types.CHECKOUT_REQUEST)
+    // shop API は成功コールバックと失敗コールバックを受け入れます
+    shop.buyProducts(
+      products,
+      // 成功処理
+      () => dispatch(types.CHECKOUT_SUCCESS),
+      // 失敗処理
+      () => dispatch(types.CHECKOUT_FAILURE, savedCartItems)
+    )
+  }
+}
+```
+
+また、全てのコンポーネントは全体のチェックアウトを行うために `vuex.actions.checkout(products)` を呼び出す必要があります。

+ 93 - 0
docs/ja/api.md

@@ -0,0 +1,93 @@
+# API リファレンス
+
+### Vuex.Store
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({ ...options })
+```
+
+### Vuex.Store コンストラクタオプション
+
+- **state**
+  
+  - 型: `Object`
+
+    Vuex store 向けの root なステートオブジェクト
+
+    [詳細](state.md)
+
+- **mutations**
+
+  - 型: `Object | Array<Object>`
+
+    各エントリキーがミューテーション名とその値がミューテーションハンドラ関数である値であるオブジェクト。ハンドラ関数は常に第1引数として`state` を受信し、そして次のディスパッチ呼び出しに渡される全ての引数を受信する
+
+    オブジェクトの配列を渡す場合は、これらオブジェクトは自動的に最後のオブジェクトにいっしょにマージされる
+
+    [詳細](mutations.md)
+
+- **actions**
+
+  - 型: `Object | Array<Object>`
+
+    各エントリキーがアクション名とその値のいずれかであるオブジェクト
+
+    1. ミューテーション名の文字列。または、
+    2. 第1引数として store を受信する関数、第2引数以降は追加されたペイロード引数
+
+    Vuex はこれらエントリを処理し、そして実際に呼び出し可能なアクション関数を作成し、さらに store の `actions` プロパティを公開する
+
+    オブジェクトの配列を渡す場合は、これらオブジェクトは自動的に最後のオブジェクトにいっしょにマージされる
+
+    [詳細](actions.md)
+
+- **middlewares**
+
+  - 型: `Array<Object>`
+
+    ミドルウェアオブジェクトの配列で以下のような形式であること:
+
+    ``` js
+    {
+      snapshot: Boolean, // default: false
+      onInit: Function,
+      onMutation: Function
+    }
+    ```
+
+    全てのフィールドは任意 [詳細](middlewares.md)
+
+- **strict**
+
+  - 型: `Boolean`
+  - デフォルト値: `false`
+
+    Vuex store を 厳格モードに強制する。厳格モードではミューテーションハンドラの外側の Vuex ステートに任意に変異するとき、エラーを投げる
+
+    [詳細](strict.md)
+
+### Vuex.Store インスタンスプロパティ
+
+- **state**
+
+  - 型: `Object`
+
+    root なステート。読み取り専用
+
+- **actions**
+
+  - 型: `Object`
+
+    呼び出し可能なアクション関数
+
+### Vuex.Store インスタンスメソッド
+
+- **dispatch(mutationName: String, ...args)**
+
+  直接ミューテーションをディスパッチする。これは一般的には、アプリケーションコードでアクションを使用するほうが必要な場合のような、特定の状況で有用
+
+- **hotUpdate(newOptions: Object)**
+
+  ホットスワップな新しいアクションとミューテーション [詳細](hot-reload.md)

+ 1 - 0
docs/ja/book.json

@@ -0,0 +1 @@
+../book.json

+ 31 - 0
docs/ja/concepts.md

@@ -0,0 +1,31 @@
+# 中核概念
+
+Vuex Store を作成するために `Vuex.Store` コンストラクタを使用できます。ほとんどの場合、各アプリケーション毎に単独の store だけが必要になります。各 Vuex Store は 3 種類の "構成要素" からなります:
+
+- **ステート**: アプリケーション状態を表すプレーンなオブジェクト
+
+- **ミューテーション**: 状態を変異させる関数。ミューテーションは**同期**必須
+
+- **アクション**: ミューテーションをディスパッチする関数。アクションは非同期操作を含めることができ、複数のミューテーションをディスパッチすることができます
+
+どうして、状態を操作する単純な機能よりもむしろ、*ミューテーション*と*アクション*を区別したいのでしょうか?その理由は、**ミューテーションを分離したいのと非同期**のためです。多くの複雑なアプリケーションは 2 つの組合せから成り立ちます。分離すると、それら両方を調査することが容易になり、そしてそれらのためのテストを書くこともできます。
+
+> Flux について精通している場合、ここでの用語/概念の違いがあることに注意してください。Vuex のアクションは Flux の**アクションクリエータ (action creators)** と同等でありますが、Vuex のミューテーションは Flux の **アクション (actions)** に相当します。
+
+### Vuex Store の作成
+
+> **NOTE:** 残りのドキュメント向けのコード例に対して ES2015 シンタックスを使用します。それについて理解できない場合は、[ここで](https://babeljs.io/docs/learn-es2015/)で学習してください!ドキュメントは既に[大規模アプリケーションの構築](http://vuejs.org/guide/application.html)で説明した概念にに精通している前提としています。
+
+Vuex Store を作成することは非常に簡単です。上記の構成要素を一緒に入れると下記になります:
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({
+  state: { ... },
+  actions: { ... },
+  mutations: { ... }
+})
+```
+
+一度作成すると、ステートは `store.state` 経由、アクションは `store.actions` 経由でアクセスすることができます。ミューテーション関数は直接アクセスすることはできません。ミューテーション関数は、アクションによるトリガされた時だけ、もしくは `store.dispatch()` を呼び出すときにアクセスできます。次の詳細で各概念について説明します。

+ 92 - 0
docs/ja/data-flow.md

@@ -0,0 +1,92 @@
+# データフロー
+
+Vuex アプリケーション内部のデータフローをより理解を得るために、Vuex で単純にカウンタするアプリケーションを構築してみましょう。これは概念を説明する目的のための簡単な例であることに注意してください。実際には、このような単純なタスクのために Vuex は必要ありません。
+
+### セットアップ
+
+``` js
+// store.js
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+```
+
+### アプリケーションのステートを定義
+
+``` js
+const state = {
+  count: 0
+}
+```
+
+### ステート可能なミューテーションを定義
+
+``` js
+const mutations = {
+  INCREMENT (state) {
+    state.count++
+  },
+  DECREMENT (state) {
+    state.count--
+  }
+}
+```
+
+### 呼び出し可能なアクションを定義
+
+``` js
+const actions = {
+  increment: 'INCREMENT',
+  decrement: 'DECREMENT'
+}
+```
+
+### Vuex Store を作成
+
+``` js
+export default new Vuex.Store({
+  state,
+  mutations,
+  actions
+})
+```
+
+### Vue コンポーネントでの使用
+
+**テンプレート**
+
+``` html
+<div>
+  Clicked: {{ count }} times
+  <button v-on:click="increment">+</button>
+  <button v-on:click="decrement">-</button>
+</div>
+```
+
+**スクリプト**
+
+``` js
+import store from './store.js'
+
+export default {
+  computed: {
+    // 算出プロパティ(computed property) を使用してステートにバインド
+    count () {
+      return store.state.count
+    }
+  },
+  methods: {
+    increment: store.actions.increment,
+    decrement: store.actions.decrement
+  }
+}
+```
+
+ここでは、コンポーネントが非常に単純であることに注意しましょう。それは単に Vuex store からいくつかのステートを表示し(データそれ自身でさえ所有しません)、そしてユーザー入力イベントでいくつかの store のアクションを呼び出します。
+
+Flux であるような、データの流れが一方向であることに注意しましょう:
+
+<p align="center">
+  <img width="700px" src="vuex.png">
+</p>

+ 36 - 0
docs/ja/forms.md

@@ -0,0 +1,36 @@
+# フォームのハンドリング
+
+厳格モードで Vuex を使用するとき、Vuex に属するステートの一部において `v-model` を使用するためには少しトリッキーです:
+
+``` html
+<input v-model="obj.message">
+```
+
+`obj` が store からオブジェクトを返す算出プロパティ (computed property) と仮定すると、`v-model` はここでは、input でユーザーがタイプするとき、直接 `obj.message` を変異させようとします。厳格モードにおいて、ミューテーションは明示的に Vuex のミューテーションハンドラ内部で処理されていないため、エラーを投げます。
+
+それに対処するための "Vuex way" は、`<input>` の値をバインディングし、そして `input` または `change` イベントでアクションを呼び出します:
+
+``` html
+<input :value="obj.message" @input="updateMessage">
+```
+``` js
+// ...
+methods: {
+  updateMessage: function (e) {
+    store.actions.updateMessage(e.target.value)
+  }
+}
+```
+
+`updateMessage` アクションが単に `'UPDATE_MESSAGE'` をディスパッチすると仮定すると、ここではミューテーションハンドラは以下のようになります:
+
+``` js
+// ...
+mutations: {
+  UPDATE_MESSAGE (state, message) {
+    state.obj.message = message
+  }
+}
+```
+
+確かに、これはかなりシンプルな `v-model` よりも冗長ですが、これは、明示的で追跡可能なステートの変化させるためのコストです。同時に、Vuex は Vuex store 内部の全てのステートを置く必要がないということに注意してください。フォームのインタラクションの全てにおいて、ミューテーションの追跡を望まない場合は、単純にコンポーネントのローカルステートとして Vuex の外部にフォームのステートを保つことができ、これは自由に `v-model` を活用することができます。

+ 29 - 0
docs/ja/hot-reload.md

@@ -0,0 +1,29 @@
+# ホットリローディング
+
+Vuex は開発においてホットリローディングなアクションとミューテーションをサポートします。Webpack は [Hot Module Replacement API](https://webpack.github.io/docs/hot-module-replacement.html) を使用します。Browserify においても [browserify-hmr](https://github.com/AgentME/browserify-hmr/) プラグインによって使用することができます。
+
+新しいアクションとミューテーションによって `store.hotUpdate()` として呼び出すのと同じくらい簡単です:
+
+``` js
+// ...
+const store = new Vuex.Store({
+  state,
+  actions,
+  mutations
+})
+
+if (module.hot) {
+  // ホットモジュールとしてアクションとモジュールを受け付ける
+  module.hot.accept(['./actions', './mutations'], () => {
+    // 更新されたモジュールをインポートする
+    // babel 6 モジュール出力のため、ここでは .default を追加しなければならない
+    const newActions = require('./actions').default
+    const newMutations = require('./mutations').default
+    // 新しいアクションとミューテーションにスワップ
+    store.hotUpdate({
+      actions: newActions,
+      mutations: newMutations
+    })
+  })
+}
+```

+ 13 - 0
docs/ja/intro.md

@@ -0,0 +1,13 @@
+## Vuex は何ですか?
+
+Vuex は Vue.js アプリケーションで集中状態管理するためのアプリケーションアーキテクチャです。[Flux](https://facebook.github.io/flux/) や [Redux](https://github.com/rackt/redux) からインスピレーションを得ていますが、 簡易化された概念、そして Vue.js リアクティブシステムの長所を得るために、特別に設計された実装になっています。
+
+## なぜこれを必要とするのですか?
+
+あなたのアプリケーションが非常に単純であるならば、多分 Vuex は必要ないでしょう。それを早まって適用しないでください。しかし、中〜大規模な SPA を構築する場合は、あなたの Vue コンポーネントの外側でどうやってよりよい構造物にするかについて考える状況に遭遇する機会です。これは Vuex の出番です。
+
+Vue.js を単独て使用するとき、しばしば、私達のコンポーネントの"内部"状態を保持します。つまり、各コンポーネントは、私達のアプリケーション状態の一部を所有しており、結果として状態があらゆる場所に散在しています。しかしながら、時どき状態の一部は、複数のコンポーネントにより共有される必要があります。一般的に見られる経験として、あるコンポーネントがいくつかの状態を他のコンポーネントにカスタムイベントシステムを使用して"送ろう"とします。このパターンの問題は、大規模なコンポーネントツリー内部のイベントフローはすぐに複雑にでき、しばしばうまく動作しない場合はそれについて原因を調査するのは難しいです。
+
+大規模アプリケーションで状態を共有させるために優れた対処として、**コンポーネントのローカル状態**と**アプリケーションレベルの状態**を区別する必要があります。アプリケーション状態は特定のコンポーネントに属していませんが、私達のコンポーネントはリアクティブな DOM 更新のためにそれを監視できます。1 つの場所でそれを集中的に管理することによって、あるコンポーネントがそこに属する必要よりも全てに影響を与えるため、もはやイベントあちこちを渡す必要はありません。加えて、私達は、記録と状態変化の理解を容易にするための全ての変異を検査することができ、タイムトラベルデバッグのような派手なものも実装可能です。
+
+Vuex はまた、どのように異なる場所に状態管理ロジックを分離するか、いくつか意見を強制しますが、それでも実際のコード構造に対して十分な柔軟性を可能します。

+ 81 - 0
docs/ja/middlewares.md

@@ -0,0 +1,81 @@
+# ミドルウェア
+
+Vuex store は各ミューテーション(これは Redux のミドルウェアとは全く無関係であることに注意してください)に対して公開された hook を `middlewares` オプションとして受け入れます。Vuex のミドルウェアは単純にいくつかの hook 関数を実装したオブジェクトです:
+
+``` js
+const myMiddleware = {
+  onInit (state) {
+    // 初期ステートを記録
+  },
+  onMutation (mutation, state) {
+    // 全ての変異後に呼ばれる
+    // ミューテーションは { type, payload } の形式で来る
+  }
+}
+```
+
+そして、このように使用することができます:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  middlewares: [myMiddleware]
+})
+```
+
+デフォルトでは、ミドルウェアは実際 `state` オブジェクトを受信します。ミドルウェアは主にデバッギング目的やデータの永続化のために使用されるため、ミドルウェアでは、**ステートを変異することができません**。
+
+時どき、ミドルウェアはステートの"スナップショット"を受信することができ、また事前のミューテーションの状態と事後のミューテーションの状態を比較したいかもしれません。このようなミドルウェアは `snapshot: true` オプションを宣言しなければなりません:
+
+``` js
+const myMiddlewareWithSnapshot = {
+  snapshot: true,
+  onMutation (mutation, nextState, prevState) {
+    // prevState と nextState は完全コピーされた(deep-cloned)、
+    // 前のミューテーションの後のミューテーションのスナップショット
+  }
+}
+```
+
+**ステートのスナップショットを撮るミドルウェアは開発時のみに使用すべきです。** Webpack または Browserify を使用するとき、私たちのためにビルドツールがそれを処理することができます:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  middlewares: process.env.NODE_ENV !== 'production'
+    ? [myMiddlewareWithSnapshot]
+    : []
+})
+```
+
+ミドルウェアはデフォルトで使用されるでしょう。本番環境のため、`process.env.NODE_ENV !== 'production'` の値を `false` に変換するために、[ここ](http://vuejs.org/guide/application.html#Deploying_for_Production) で説明したビルドセットアップを最終ビルド向けに使用します。
+
+### ビルドイン Logger ミドルウェア
+
+Vuex は一般的なデバッギングを使用するための logger ミドルウェアが付属しています:
+
+``` js
+const store = new Vuex.Store({
+  middlewares: [Vuex.createLogger()]
+})
+```
+
+`createLogger` 関数はいくつかのオプションがあります:
+
+``` js
+const logger = Vuex.createLogger({
+  collapsed: false, // ログに記録されたミューテーションを自動拡大する
+  transformer (state) {
+    // それを記録す前にステートを変換する
+    // 例えば、特定のサブツリーだけ返します
+    return state.subTree
+  },
+  mutationTransformer (mutation) {
+    // ミューテーションは { type, payload } の形式で記録される
+    // どんな形式でも欲しいフォーマットに変換できる
+    return mutation.type
+  }
+})
+```
+
+ステートのスナップショットを撮る logger ミドルウェアは開発時のみ使用することに注意してください。

+ 95 - 0
docs/ja/mutations.md

@@ -0,0 +1,95 @@
+# ミューテーション
+
+Vuex のミューテーションは基本的にイベントです。各ミューテーションは**名前**と**ハンドラ**を持ちます。ハンドラ関数は常に全体のステートツリーを第1引数として取得します:
+
+``` js
+import Vuex from 'vuex'
+
+const store = new Vuex.Store({
+  state: {
+    count: 1
+  },
+  mutations: {
+    INCREMENT (state) {
+      // 変異するステート
+      state.count++
+    }
+  }
+})
+```
+
+ミューテーション名に対して全て大文字を使用するのは、容易にアクションと区別できるようにするための規則です。
+
+直接ミューテーションハンドラ呼び出すことはできません。ここでのオプションは、よりイベント登録のようなものです。"`INCREMENT` イベントがディスパッチされるとき、このハンドラは呼ばれます。"ミューテーションハンドラを起動するためには、ミューテーションイベントをディスパッチする必要があります:
+
+``` js
+store.dispatch('INCREMENT')
+```
+
+### 引数によるディスパッチ
+
+引数に沿って渡すことも可能です:
+
+``` js
+// ...
+mutations: {
+  INCREMENT (state, n) {
+    state.count += n
+  }
+}
+```
+``` js
+store.dispatch('INCREMENT', 10)
+```
+
+ここの `10` は `state` に続く第2引数としてミューテーションハンドラに渡されます。任意の追加引数と同じです。これら引数は、特定のミューテーションに対して**ペイロード**と呼ばれています。
+
+### Vue のリアクティブなルールに従うミューテーション
+
+Vuex store のステートは Vue によってリアクティブになっているので、ステートを変異するとき、ステートを監視している Vue コンポーネントは自動的に更新されます。これはまた、Vuex のミューテーションは、純粋な Vue で動作しているとき、同じリアクティブな警告の対象となっているのを意味します:
+
+1. 前もって全て望まれるフィールドによって、あなたの store の初期ステートを初期化することを好みます
+
+2. 新しいプロパティをオブジェクトに追加するとき、いずれか必要です:
+
+  - `Vue.set(obj, 'newProp', 123)` を使用または -
+
+  - 全く新しいものでオブジェクトを置き換える。例えば、stage-2 の [object spread syntax](https://github.com/sebmarkbage/ecmascript-rest-spread) を使用して、このようにそれを書くことができます:
+
+  ``` js
+  state.obj = { ...state.obj, newProp: 123 }
+  ```
+
+### ミューテーション名に対して定数を使用
+
+ミューテーション名には定数を使用することが一般的です。コードに対してリンタのようなツールの長所を利用することができ、そして、単一ファイルに全ての定数を設定することは、あなたの協力者にミューテーションがアプリケーション全体で可能であるかが一目見ただけで理解できるビューを得ることができます:
+
+``` js
+// mutation-types.js
+export const SOME_MUTATION = 'SOME_MUTATION'
+```
+
+``` js
+// store.js
+import Vuex from 'vuex'
+import { SOME_MUTATION } from './mutation-types'
+
+const store = new Vuex.Store({
+  state: { ... },
+  actions: { ... },
+  mutations: {
+    // 定数を関数名として使用できる ES2015 の算出プロパティ (computed property) 名機能を使用できます
+    [SOME_MUTATION] (state) {
+      // 変異するステート
+    }
+  }
+})
+```
+
+定数を使用するかどうか大部分が好みであり、それは多くの開発者による大規模アプリケーションで役に立ちますが、好きではないならば、それは完全にオプションです。
+
+### アクションの上へ
+
+これまでのところ、`store.dispatch` の手動呼び出しによってミューテーションをトリガしていました。これは実行可能なアプローチですが、実際には私たちのコンポーネントのコードでこれを行うことはほとんどありません。ほとんどの時間、[アクション](actions.md) を呼び出し、非同期データフェッチングのようなより複雑なロジックをカプセル化することができます。
+
+また、全てのミューテーションハンドラは**同期**でなければならないという、1つ重要なルールを覚えておきましょう。任意の非同期な操作はアクションに属しています。

+ 2 - 0
docs/ja/quickstart.md

@@ -0,0 +1,2 @@
+# Quickstart
+

+ 51 - 0
docs/ja/state.md

@@ -0,0 +1,51 @@
+# ステート
+
+### 単一ステートツリー
+
+Vuex は**単一ステートツリー (single state tree)**を使用します。つまり、この単一なオブジェクトはあなたのアプリケーションレベルの状態が全て含まれており、"信頼できる唯一の情報源 (single source of truth)" として機能します。これは状態の特定の部分を見つけることが容易になり、そしてデバッギング目的のために現在のアプリケーション状態のスナップショットを取ることも容易にできます。
+
+単一ステートツリーはモジュールとコンフリクト(競合)しません。以降の章では、あなたの状態管理ロジックをサブモジュールにおいてどうやって分離するかについて説明します。
+
+### Vue コンポーネントにおいて Vuex ステートを取得する
+`state` オブジェクトは、Vue インスタンスに渡される `data` オブジェクトに似ており、一度 Vuex store に渡され、[Vue のリアクティブシステム](http://vuejs.org/guide/reactivity.html) によってリアクティブになります。これは、Vue コンポーネントにバインディングする Vuex state は、算出プロパティ (computed property) の中からそれを返すのと同じくらい簡単なことを意味します:
+
+``` js
+// Vue コンポーネントモジュール内部
+
+// vuex store をインポート
+import store from './store'
+
+export default {
+  computed: {
+    message () {
+      return store.state.message
+    }
+  }
+}
+```
+
+store にコンポーネントを設定し、そしてリスナを切断または"接続する"心配の必要はりません。覚えておくくべき唯一のことは、**常にあなたの算出プロパティ内部で `store.state.xxx` 経由でステートを参照する**必要があるということです。算出プロパティ外のステートの一部への参照をキャッシュしないでください。
+
+> Flux リファレンス: これは雑ですが Redux での [`mapStateToProps`](https://github.com/rackt/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options) と NuclearJS での [getters](https://optimizely.github.io/nuclear-js/docs/04-getters.html) と比較することができます。
+
+なぜ、ステートにバインドするために `data` を使用しないのでしょうか?次の例を考えてみます:
+
+``` js
+export default {
+  data () {
+    return {
+      message: store.state.message
+    }
+  }
+}
+```
+
+`data` 関数は任意のリアクティブな依存関係を追跡していないため、`store.state.message` への静的な参照だけを取得してます。ステートが後で変異したとき、コンポーネントは何かが変化しときのアイデアを持っていません。比較して、算出プロパティはそれらが評価されたときリアクティブな依存関係を全て追跡し、関連するステートが変異されているとき、反応性を再評価します。
+
+### コンポーネントは直接ステートを変異することはできない
+
+読み取り専用の算出プロパティを使用すると、**コンポーネントは直接 Vuex store のステートを変異させるべきではない**というルールを強調するのを援助するという別の利点を持っています。全てのステートのミューテーションを明示的および追跡可能にしたいため、全ての vuex store のミューテーションは store のミューテーションハンドラ内部で行われければなりません。
+
+このルールを強制するのを援助するために、[厳格モード](strict.md) で store のステートがミューテーションハンドラの外部で変異された場合は、Vuex はエラーを投げます。
+
+代わりにこのルールでは、私達の Vue コンポーネントははるかに少ない責務で済みます。読み取り専用の算出プロパティを介して Vuex store のステートにバインドされており、ステートに影響を与えるための唯一の方法は、**アクション**によって呼び出され、順番に**ミューテーション** をトリガすることです。必要であれば、まだ所有しローカルステートに操作できますが、もはや個々のコンポーネント内部には、任意のデータフェッチまたはグローバルステートミューテーティングロジックを入れていません。

+ 25 - 0
docs/ja/strict.md

@@ -0,0 +1,25 @@
+# 厳格モード
+
+厳格モードを有効にするには、Vuex store を作成するときに、単純に `strict: true` を指定します:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: true
+})
+```
+
+厳格モードでは、Vuex のステートがミューテーションハンドラの外部で変異されたときはいつでも、エラーを投げます。これは全てのステートの変異がデバッギングツールによって明示的に追跡dけいるようになります。
+
+### 開発環境 vs 本番環境
+
+**本番環境に対して 厳格モードを有効にしてデプロイしてはなりません!** 厳格モードでは不適切なミューテーションを検出するためにステートツリー上で深い監視を実行します。パフォーマンスコストを回避するために本番環境ではそれをオフにしてください。
+
+ミドルウェアと同様に、ビルドツールに処理させることができます:
+
+``` js
+const store = new Vuex.Store({
+  // ...
+  strict: process.env.NODE_ENV !== 'production'
+})
+```

+ 133 - 0
docs/ja/structure.md

@@ -0,0 +1,133 @@
+# アプリケーションの構造
+
+Vuex は本当にあなたのコードを構造化する方法を制限するものでありません。むしろ以下の見解が求められます:
+
+1. アプリケーションステートは単一オブジェクトで生存します
+2. ミューテーションハンドラだけステートを変異できます
+3. ミューテーションは同期でなければなく、そしてそれらを作成するだけの副作用はミューテーションとステートになるべきです
+4. データフェッチングのような全ての非同期ロジックはアクションで実行されるべきです
+
+Vuex のアクションとミューテーションの良いところは、**それらは関数である**ということです。これらのルールに従っている限り、あなたのプロジェクトで構造化する方法はあなた次第です。最も単純な Vuex インスタンスは[単一ファイルで](https://github.com/vuejs/vuex/blob/master/examples/counter/vuex.js)さえ宣言できるということです!しかしながら、これは任意の重大なプロジェクトに対しては十分ではなく、ここではあなたのアプリケーションの規模に応じて、いくつか推奨される構造を紹介します。
+
+### 単純なプロジェクト
+
+単純なプロジェクトに対しては、単純に**アクション**と**ミューテーション**をそれぞれのファイルに分離することができます:
+
+``` bash
+.
+├── index.html
+├── main.js
+├── components
+│   ├── App.vue
+│   └── ...
+└── store
+    ├── index.js     # vuex store をエクスポート
+    ├── actions.js   # 全てのアクションをエクスポート
+    └── mutations.js # 全てのミューテーションをエクスポート
+```
+
+実際の例として、[TodoMVC example](https://github.com/vuejs/vuex/tree/master/examples/todomvc) を確認してください。
+
+### 中〜大規模プロジェクト
+
+任意の素晴らしいアプリケーションに対して、多分、Vuex 関連のコードをさらに私たちのアプリケーションを特定のドメインによって各お気に入りの複数"モジュール" (雑にいうと、純粋な Flux で "stores" にほぼ匹敵)に分離したいです。各サブモジュールはステートのサブツリーを管理することになり、そのサブツリーとそのサブツリーで操作する全てのミューテーションに対する初期ステートをエクスポートします:
+
+``` bash
+├── index.html
+├── main.js
+├── api
+│   └── ... # API リクエストを作成するために抽象化
+├── components
+│   ├── App.vue
+│   └── ...
+└── store
+    ├── actions.js # 全てのアクションをエクスポート
+    ├── index.js
+    ├── modules
+    │   ├── cart.js       # ステートとカート向けのミューテーション
+    │   └── products.js   # ステートと製品向けのミューテーション
+    └── mutation-types.js # 定数
+```
+
+典型的なモジュールは次のようになります:
+
+``` js
+// vuex/modules/products.js
+import { RECEIVE_PRODUCTS, ADD_TO_CART } from '../mutation-types'
+
+// 初期ステート
+export const productsInitialState = []
+
+// ミューテーション
+export const productsMutations = {
+  [RECEIVE_PRODUCTS] (state, products) {
+    state.products = products
+  },
+
+  [ADD_TO_CART] ({ products }, productId) {
+    const product = products.find(p => p.id === productId)
+    if (product.inventory > 0) {
+      product.inventory--
+    }
+  }
+}
+```
+
+そして `store/index.js` では、Vuex インスタンスを作成するために複数のモジュールをいっしょに"組み立てます(assemble)":
+
+``` js
+import Vue from 'vue'
+import Vuex from '../../../src'
+import * as actions from './actions'
+// modules からパーツをインポート
+import { cartInitialState, cartMutations } from './modules/cart'
+import { productsInitialState, productsMutations } from './modules/products'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+  // ...
+  // root なステートにサブツリーを結合
+  state: {
+    cart: cartInitialState,
+    products: productsInitialState
+  },
+  // ミューテーションは複数の modules から
+  // ミューテーション定義オブジェクトの配列にすることが可能
+  mutations: [cartMutations, productsMutations]
+})
+```
+
+全てのモジュールは単純にオブジェクトと関数をエクスポートするため、テストとメンテナンスすることが非常に簡単です。また、あなたの好みに合った構造を見つけるためにここで使用されるパターンを変えることは自由です。
+
+単一のアクションは、複数のモジュールに影響を与えるミューテーションをディスパッチする可能性があるため、モジュールにアクションを置いていないことに注意してください。また、ステートの形式と、より良い関心事の分離のためにミューテーションの実装詳細からアクションを分離するもの良いアイデアです。アクションファイルが大きくなりすぎた場合は、フォルダにそれを格納し、個々のファイルへ長い非同期アクションの実装を分割できます。
+
+実際の例として、[Shopping Cart Example](https://github.com/vuejs/vuex/tree/master/examples/shopping-cart) を確認してください。
+
+### 共有された算出プロパティ Getter の抽出
+
+大規模なプロジェクトでは、複数のコンポーネントが Vuex のステートに基づいて同じ算出プロパティ (computed property) を必要とする可能性があります。算出プロパティは単に関数であるため、それらが任意のコンポーネントで共有することができるように、ファイルにそれらを分割することができます:
+
+``` js
+// getters.js
+import store from './store'
+
+export function filteredTodos () {
+  return store.state.messages.filter(message => {
+    return message.threadID === store.state.currentThreadID
+  })
+}
+```
+
+``` js
+// コンポーネントで...
+import { filteredTodos } from './getters'
+
+export default {
+  computed: {
+    filteredTodos
+  }
+}
+```
+
+これはとても [NuclearJS での Getter](https://optimizely.github.io/nuclear-js/docs/04-getters.html) と似ています。

+ 135 - 0
docs/ja/testing.md

@@ -0,0 +1,135 @@
+# テスト
+
+ミューテーションは完全に引数に依存しているだけの関数であるため、テストするのがとても簡単です。アクションは外部の API を呼び出す可能性があるためより少し注意が必要です。アクションをテストするとき、通常モックのいくつかのレベルで実行する必要があります。例えば、サービスでの API 呼び出しを抽象化することができ、そしてテスト内部でサービスをモックにすることができます。簡単に依存を真似るために、Webpack と [inject-loader](https://github.com/plasticine/inject-loader) をテストファイルにバンドルして使用することができます。
+
+ミューテーションやアクションが適切に書かれている場合は、テストは適切なモック後、ブラウザの API に直接依存関係を持つべきではありません。したがって、単純に Webpack でテストをバンドルでき、それを直接 Node で実行できます。別の方法として、本当のブラウザでテストを実行するためには、`mocha-loader` または Karma + `karma-webpack` を使用できます。
+
+Mocha + Chai を使用してミューテーションをテストする例です (好きな任意のフレームワーク/アサーションライブラリを使用できます):
+
+``` js
+// mutations.js
+export const INCREMENT = state => state.count++
+```
+
+``` js
+// mutations.spec.js
+import { expect } from 'chai'
+import { INCREMENT } from './mutations'
+
+describe('mutations', () => {
+  it('INCREMENT', () => {
+    // モックステート
+    const state = { count: 0 }
+    // ミューテーションを適用
+    INCREMENT(state)
+    // 結果を検証
+    expect(state.count).to.equal(1)
+  })
+})
+```
+
+Example testing an async action:
+
+``` js
+// actions.js
+import shop from '../api/shop'
+
+export const getAllProducts = ({ dispatch }) => {
+  dispatch('REQUEST_PRODUCTS')
+  shop.getProducts(products => {
+    dispatch('RECEIVE_PRODUCTS', products)
+  })
+}
+```
+
+``` js
+// actions.spec.js
+
+// inline loader に対して require 構文を使用する
+// inject-loader は、真似られた依存関係を注入できるようにする
+// モジュールファクトリを返す
+import { expect } from 'chai'
+const actionsInjector = require('inject!./actions')
+
+// モックによってモジュールを作成する
+const actions = actionsInjector({
+  '../api/shop': {
+    getProducts (cb) {
+      setTimeout(() => {
+        cb([ /* 真似られたスポンス */ ])
+      }, 100)
+    }
+  }
+})
+
+// ミューテーションによって予期されたアクションをテストするためのヘルパー
+const testAction = (action, state, expectedMutations, done) => {
+  let count = 0
+  // モックディスパッチ
+  const dispatch = (name, payload) => {
+    const mutation = expectedMutations[count]
+    expect(mutation.name).to.equal(name)
+    if (payload) {
+      expect(mutation.payload).to.deep.equal(payload)
+    }
+    count++
+    if (count >= expectedMutations.length) {
+      done()
+    }
+  }
+  // 真似られた store によってアクションを呼び出す
+  action({
+    dispatch,
+    state
+  })
+}
+
+describe('actions', () => {
+  it('getAllProducts', done => {
+    testAction(actions.getAllProducts, {}, [
+      { name: 'REQUEST_PRODUCTS' },
+      { name: 'RECEIVE_PRODUCTS', payload: [ /* 真似られたレスポンス */ ] }
+    ], done)
+  })
+})
+```
+
+### Node での実行
+
+以下のような webpack の設定を作成します:
+
+``` js
+module.exports = {
+  entry: './test.js',
+  output: {
+    path: __dirname,
+    filename: 'test-bundle.js'
+  },
+  module: {
+    loaders: [
+      {
+        test: /\.js$/,
+        loader: 'babel',
+        exclude: /node_modules/
+      }
+    ]
+  },
+  babel: {
+    presets: ['es2015']
+  }
+}
+```
+
+その後、下記コマンドを実行します:
+
+``` bash
+webpack
+mocha test-bundle.js
+```
+
+### ブラウザでの実行
+
+1. `mocha-loader` をインストール
+2. 上記 Webpack 設定から `entry` を `'mocha!babel!./test.js'` に変更
+3. 設定を使用して `webpack-dev-server` を開始
+4. `localhost:8080/webpack-dev-server/test-bundle` に移動

二进制
docs/ja/vuex.png