Quellcode durchsuchen

[Doc zh-cn] First patch of chinese translation update (#179)

* Update SUMMARY.md Ref vuejs/vuex#176

* Retranslate intro.md

* RENAME quickstart.md file to gettings-started to follow the same structure with upstream

* complete the profreading of getting-started

* more profreading

* Remove concepts.md to follow the same exact structure changes of upstream.\n It is quite redundant with getting-started.md actually.

* complete profreading of tutorial.md

* [WIP] Stage & getters

* [WIP]translate to "Sharing Getters Across Multiple Components"

* More general name of getting started section

* complete state.md file translation

* Change the term used, due to vuejs/vuex/#182
东方孤思子 Paris·QianSen vor 9 Jahren
Ursprung
Commit
a963ac474d

+ 8 - 7
docs/zh-cn/SUMMARY.md

@@ -1,13 +1,14 @@
 # 目录
 
-> 注意:中文版文档目前只更新到 0.2.x 版本,最新版本的文档请看英文版。
+> 注意:中文版文档更新可能滞后,最新版本的文档请看英文版。  
+> 请确保按顺序阅读
 
 - [什么是 Vuex?](intro.md)
-- [快速开始](quickstart.md)
-- [教程](tutorial.md)
-- [核心概念](concepts.md)
-  - [State](state.md)
-  - [Mutations](mutations.md)
+- [准备开始](getting-started.md)
+- [简易教程](tutorial.md)
+- 核心概念
+  - [State 和 Getters](state.md)
+  - [Mutations(状态变更)](mutations.md)
   - [Actions](actions.md)
 - [数据流](data-flow.md)
 - [应用结构](structure.md)
@@ -16,4 +17,4 @@
 - [表单处理](forms.md)
 - [测试](testing.md)
 - [热重载](hot-reload.md)
-- [API Reference](api.md)
+- [API 参考文档](api.md)

+ 0 - 33
docs/zh-cn/concepts.md

@@ -1,33 +0,0 @@
-# 核心概念
-
-你可以使用 `Vuex.Store` 构造函数来创建 Vuex store 实例。一般情况下,一个应用中只需要一个 store 实例。
-
-每个 Vuex store 实例由三个部分组成:
-
-- **State**: 一个反映应用状态的纯对象。
-
-- **Mutations**: 一些用于改变状态的函数。Mutations **必须是同步的**。
-
-- **Actions**: 一些用于触发 (dispatch) mutations 的函数。一个 action 可以包含异步操作,并且可以触发多个 mutations.
-
-我们把 *mutations* 和 *actions* 分开而不是直接用函数去操作 state,原因是我们希望把*对状态的修改*和*异步操作*分离。许多应用之所以复杂,正是源自于这两者的耦合。我们解耦两者后,它们都会变得更清晰和易于测试。
-
-> 如果你熟悉 Flux,在这里要注意两者的一些差异:Vuex mutations 相当于 Flux 的 **actions**, 而 Vuex 的 actions 相当于 Flux 的 **action creators**.
-
-### 创建一个 Vuex Store 实例
-
-> **NOTE:** 我们将用 ES2015 语法写接下来的示例代码。如果你还没开始接触 ES2015,那么你应该[现在就开始学习](https://babeljs.io/docs/learn-es2015/)! 我们还默认你已经熟悉 [Building Large-Scale Apps with Vue.js](http://vuejs.org/guide/application.html) 中所提到的概念。
-
-创建一个 Vuex store 实例非常简单——只需要把以上提到的三个部分放到一起:
-
-``` js
-import Vuex from 'vuex'
-
-const store = new Vuex.Store({
-  state: { ... },
-  actions: { ... },
-  mutations: { ... }
-})
-```
-
-实例化后,你就能通过 `store.state` 访问 state, 通过 `store.actions` 访问 actions 函数。你不能直接访问 mutation 函数 —— 你只能通过调用 actions 或是 `store.disptach()` 来触发 mutations。接下来我们会更详细地讨论这几个概念。

+ 53 - 0
docs/zh-cn/getting-started.md

@@ -0,0 +1,53 @@
+# 准备开始
+
+每一个 Vuex 应用的核心就是 **store**(仓库)。"store" 基本上就是一个容器,它包含着你应用里大部分的 **状态**(即 **state**). Vuex 和单纯的全局对象有以下两点不同:
+
+1. Vuex 的状态存储是响应式的. 当 Vue 组件从 store 中读取状态的时候, 若 store 中的状态发生变化,那么相应的组件也会相应地高效地得到更新.
+
+2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地分发 **状态变更事件**(explicitly dispatching **mutations**)。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
+
+### 最简单的 store
+
+> **注意**:我们将会在后续的文档中用 ES2015 语法进行案例展示。如果你还没能掌握 ES2015,[你得抓紧了](https://babeljs.io/docs/learn-es2015/)!本文同样假设你已经了解了 Vue 本体的官方文档中[构建大型应用](http://vuejs.org.cn/guide/application.html)章节所涉及的概念.
+
+创建 Vuex store 的过程相当直截了当 - 只要提供一个初始化的 state 对象,以及一些 mutations:
+
+``` js
+import Vuex from 'vuex'
+
+const state = {
+  count: 0
+}
+
+const mutations = {
+  INCREMENT (state) {
+    state.count++
+  }
+}
+
+export default new Vuex.Store({
+  state,
+  mutations
+})
+```
+
+现在,你可以通过 `store.state` 来读取 `state` 对象,还可以通过 dispatch 某 mutation 的名字来触发这些状态变更:
+
+``` js
+store.dispatch('INCREMENT')
+
+console.log(store.state.count) // -> 1
+```
+
+如果你倾向于对象风格的分发方式,你可以用这种语法:
+
+``` js
+// 效果同上
+store.dispatch({
+  type: 'INCREMENT'
+})
+```
+
+再次强调,我们通过分发 mutation 的方式,而非直接改变 `store.state.count`,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。
+
+以上只是一个用来展示 store 究竟是什么的一个极简栗子。但是 Vuex 可不仅仅是状态存储。接下来,我们将会更深入地探讨一些核心概念:[State(状态)](state.md),[Mutations(变更)](mutations.md) 和 [Actions(动作)](actions.md)。

+ 5 - 5
docs/zh-cn/intro.md

@@ -1,13 +1,13 @@
 ## 什么是 Vuex?
 
-Vuex 是一个专门为 Vue.js 应用设计的状态管理架构。它借鉴了 [Flux](https://facebook.github.io/flux/) 和 [Redux](https://github.com/rackt/redux) 的设计思想,但简化了概念和 API,并且采用了一种更加符合 Vue.js 的数据响应系统(reactivity system)的实现。
+Vuex 是一个专门为 Vue.js 应用设计的集中式状态管理架构。它借鉴了 [Flux](https://facebook.github.io/flux/) 和 [Redux](https://github.com/rackt/redux) 的设计思想,但简化了概念,并且采用了一种为能更好发挥 Vue.js 数据响应机制而专门设计的实现。
 
 ## 我为什么需要它?
 
-当你的应用还很简单的时候,你可能并不需要 Vuex。我也并不建议在所有的场合都使用 Vuex。但是,如果你正在构建一个较大规模的 SPA,你可能已经开始思考应该如何处理 Vue 组件之外的应用结构。这就是 Vuex 要解决的问题
+当你的应用还很简单的时候,你多半并不需要 Vuex。也不建议过早地使用 Vuex。但如果你正在构建一个中型以上规模的 SPA,你很有可能已经需要思考应该如何更好地归纳 Vue 之外,应用的其他组成部分。这就是 Vuex 要大显身手的时刻
 
-我们在用 Vue.js 的时候,通常会把状态储存在组件的内部。也就是说,每一个组件都拥有一部分状态,整个应用的状态是分散在多个地方的。然而我们经常遇到的一个需求就是需要把一部分的状态共享给其它组件。通常我们会使用 Vue 或是第三方的事件系统去达到这个目的。但基于事件的问题在于,事件流会在逐渐增长的组件树中变得复杂,并且在出现问题的时候很难去发现问题的所在(典型的如事件 ping-pong,即子组件 dispatch 到父组件,再由父组件 broadcast)
+我们在单独使用 Vue.js 的时候,通常会把状态储存在组件的内部。也就是说,每一个组件都拥有当前应用状态的一部分,整个应用的状态是分散在各个角落的。然而我们经常会需要把状态的一部分共享给多个组件。一个常见的解决策略为:使用定制的事件系统,让一个组件把一些状态“*发送*”到其他组件中。这种模式的问题在于,大型组件树中的事件流会很快变得非常繁杂,并且调试时很难去找出究竟哪错了
 
-为了更好的解决在大型应用中共享状态的问题,我们需要把组件的本地状态 (component local state) 和应用状态 (application level state) 区分开来。应用级的状态不属于任何特定的组件,但每一个组件仍然可以通过 Vue 的响应系统去侦听其变化从而自动更新 DOM。通过把应用的状态管理逻辑放在同一个地方,我们就不需要在各个地方去处理各种事件,因为任何牵扯到多个组件的东西,都会放在这个地方。这样做也能使记录和检查状态的改变成为可能,甚至可以做出像 time-travel 这样的调试功能。
+为了更好的解决在大型应用中状态的共用问题,我们需要对组件的 **组件本地状态**(component local state) 和 **应用层级状态**(application level state) 进行区分。应用级的状态不属于任何特定的组件,但每一个组件仍然可以监视(Observe)其变化从而响应式地更新 DOM。通过汇总应用的状态管理于一处,我们就不必到处传递事件。因为任何牵扯到一个以上组件的逻辑,都应该写在这里。此外,这样做也能让我们更容易地记录并观察状态的变更(Mutation,原意为突变),甚至可以实现出华丽如时光旅行一般的调试效果。(译注:是时候安利一波 [vue-devtools](https://github.com/vuejs/vue-devtools) 了)
 
-Vuex 也对状态管理的代码分离有一定程度的约束,但不会影响你实际代码结构的灵活性。
+Vuex 也对如何管理分撒各地的状态增加了一些约束,但仍保留有足够面对真实使用场景的灵活性。

+ 0 - 53
docs/zh-cn/quickstart.md

@@ -1,53 +0,0 @@
-# 快速开始
-
-每一个基于 Vuex 的应用的核心就是 **store**. "store" 基本上就是一个装有你的应用的大部分 **状态**(即 **state**)的容器. Vuex 和普通的全局对象有以下两点不同:
-
-1. Vuex 的状态存储是动态的. 当 Vue 组件从 store 中的 state 读取状态的时候, 如果 store 中的 state 改变,那么响应的组件也会动态并高效的改变.
-
-2. 你不能直接改变 store 中的 state. 改变 store 中的 state 的唯一途径就是明确的 dispatch **mutations** 事件. 这样使得每一个状态的变化都很容易追踪, 并且能够让我们通过工具更了解应用内部的状态.
-
-### 最简单的 store
-
-> **注意:** 在接下来的文档中,我们将会在后面的例子中使用 ES2015 的语法。如果你还没能掌握 ES2015,[你应该这样](https://babeljs.io/docs/learn-es2015/)! 文档同样也认为你已经熟悉了 [Building Large-Scale Apps with Vue.js](http://vuejs.org/guide/application.html) 中所涉及的概念.
-
-创建 Vuex 的 store 相当直截了当 - 只要提供一个初始化的 state 对象,以及一些 mutations:
-
-``` js
-import Vuex from 'vuex'
-
-const state = {
-  count: 0
-}
-
-const mutations = {
-  INCREMENT (state) {
-    state.count++
-  }
-}
-
-const store = new Vuex.Store({
-  state,
-  mutations
-})
-```
-
-现在,你可以通过 `store.state` 来读取状态对象,还可以通过 dispatch mutation 的名字来触发改变:
-
-``` js
-store.dispatch('INCREMENT')
-
-console.log(store.state.count) // -> 1
-```
-
-如果你更喜欢对象风格的 dispatch,你也可以这么做:
-
-``` js
-// 同上例效果
-store.dispatch({
-  type: 'INCREMENT'
-})
-```
-
-再次强调,我们通过 dispatch 一个 mutation 而不是直接改变 `store.state.count`,是因为我们想要明确追踪状态的变化。这个简单的约定,能够让你不会状态混乱,这让应用状态改变的时候,在代码中能够更好的定位。此外,这样也给了我们机会通过工具来记录每次状态改变、状态快照、甚至像时间旅行一样调试。
-
-这里只是一个最简单的理解展示 store 的状态存储。但是 Vuex 不仅仅是状态存储。接下来,我们将会深入探讨一些核心概念:[State](state.md), [Mutations](mutations.md) 和 [Actions](actions.md).

+ 28 - 30
docs/zh-cn/state.md

@@ -1,17 +1,17 @@
 # State 和 Getters
 
-### 单状态树
+### 单状态树
 
-Vuex 使用**单状态树** —— 也就是单个对象作为『单一数据提供源([SSOT](https://en.wikipedia.org/wiki/Single_source_of_truth))』来管理整个应用级别的状态。这也意味着每个应用仅需一个 store 实例。单状态树使得我们能够直截了当地定位某一部分特定的状态,在调试的过程中也能轻易地取得当前应用状态的快照。
+Vuex 使用 **单一状态树** —— 是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源([SSOT](https://en.wikipedia.org/wiki/Single_source_of_truth))』而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
 
-单状态树和模块化并不冲突 —— 在往后的章节里我们会讨论如何将状态管理分离到各个子模块中。
+单状态树和模块化并不冲突 —— 在后面的章节里我们会讨论如何将状态和状态变更事件分布到各个子模块中。
 
 ### 在 Vue 组件中获得 Vuex 状态
 
-那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是动态的,从 store 实例中读取状态最简单的方法就是在计算属性 [computed property](http://vuejs.org/guide/computed.html) 中返回某个状态:
+那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性 [computed property](http://vuejs.org.cn/guide/computed.html) 中返回某个状态:
 
 ``` js
-// 在 Vue 组件定义时
+// 在某个 Vue 组件的定义对象里
 computed: {
   count: function () {
     return store.state.count
@@ -19,9 +19,9 @@ computed: {
 }
 ```
 
-每当 `store.state.count` 变化的时候, 都会使得计算属性重新计算,并且触发相关联的 DOM 更新
+每当 `store.state.count` 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM
 
-然而,这种模式导致组件依赖全局状态。这导致测试单个组件和多个实例共享一套组件变得困难。在大型应用中,我们也许需要把状态从根组件『注入』到每一个子组件中。下面便是如何实现:
+然而,这种模式导致组件依赖的全局状态单利。这导致测试组件变得更麻烦,同时运行多个共享一套组件的应用实例也会变得更困难。在大型应用中,我们需要把状态从根组件『注入』到每一个子组件中。下面便是如何实现:
 
 1. 安装 Vuex 并且将您的根组件引入 store 实例:
 
@@ -31,33 +31,32 @@ computed: {
   import store from './store'
   import MyComponent from './MyComponent'
 
-  // 重要,告诉 Vue 组件如何处理 Vuex 相关的配置
+  // 关键点,教 Vue 组件如何处理与 Vuex 相关的选项
   Vue.use(Vuex)
 
   var app = new Vue({
     el: '#app',
-    // 使用 “store” 选项来配置 store 实例
-    // 并会在全部的子组件中注入 store 实例
-    store,
+    // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
+    store, // 译注:简写,等效于 store: store
     components: {
       MyComponent
     }
   })
   ```
 
-  通过在根实例中注册 `store` 选项,store 实例会被注入到根组件下全部的子组件中,并且可以通过 `this.$store` 获得。不过实际上我们几乎不需要直接引用它。
+  通过在根实例中注册 `store` 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 `this.$store` 访问到。不过事实上,我们几乎不会需要直接引用它。
 
-2. 在子组件中,在 `vuex.getters` 配置中通过 **getter** 来读取状态:
+2. 在子组件中,通过在 `vuex.getters` 选项里定义的 **getter** 方法来读取状态:
 
   ``` js
   // MyComponent.js
   export default {
     template: '...',
     data () { ... },
-    // 这里是我们从 store 实例取回状态的位置
+    // 此处为我们从 store 实例中取回状态的位置
     vuex: {
       getters: {
-        // 一个状态的 getter 函数,将会把 `store.state.count` 绑定为 `this.count`
+        // 该 getter 函数将会把仓库的 `store.state.count` 绑定为组件的 `this.count`
         count: function (state) {
           return state.count
         }
@@ -66,9 +65,9 @@ computed: {
   }
   ```
 
-  留意特殊的 `vuex` 选项部分,在这里我们指定该组件将会从 store 实例中读取哪些状态。每个属性名对应一个 getter 函数,该函数接收整个状态树作为唯一参数并返回状态树的一部分或计算后的新值。组件可以像使用计算属性一样通过属性名获取 getter 函数的返回值
+  请留意 `vuex` 的这个特殊选项(译注:getters 子对象)。它是我们指定当前组件能从 store 里获取哪些状态信息的地方。它的每个属性名将对应一个 getter 函数。该函数仅接收 store 的整个状态树作为其唯一参数,之后既可以返回状态树的一部分,也可以返回从状态树中求取的计算值。而返回结果,则会依据这个 getter 的属性名添加到组件上,用法与组件自身的*计算属性*一毛一样
 
-  大多数情况下,“getter” 函数可以通过 ES2015 的箭头函数来简洁地实现
+  大多数时候,“getter” 函数可以用 ES2015 的箭头函数方法实现得非常简洁
 
   ``` js
   vuex: {
@@ -78,21 +77,20 @@ computed: {
   }
   ```
 
-### getter 函数必须是纯函数
+### Getter 函数必须是纯函数
 
-所有的 Vuex getter 函数,必须是[纯函数](https://en.wikipedia.org/wiki/Pure_function) —— 它们只依赖传入的状态树计算出返回值。这让组件更容易测试、组合和更高效。这也意味着**在 getter 函数中不能依赖 `this`**。
+所有的 Vuex getter 函数必须是[纯函数](https://en.wikipedia.org/wiki/Pure_function)(译注:在我之前还没有中文 wiki,简单来讲就是 1.计算完全依赖函数输入值,而非其他隐藏信息,若输入相同,则输出也必须相同 2. 该函数不能有语义上可观察的[函数副作用](https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0%E5%89%AF%E4%BD%9C%E7%94%A8),如“触发事件”,“其他形式的输出”等。) —— 它们取值只依赖传入的状态树。这让组件的测试和编组更容易且更高效。这也意味着:**在 getter 里你不能依赖 `this` 关键字**。
+
+如果你确实需要使用 `this`,例如需要用到组件内部的本地状态来计算些派生属性,那么你需要另外单开一个计算属性:
 
-如果你确实需要使用 `this`,例如为了基于组件的局部状态来计算派生属性,你需要另外单独定义一个计算属性:
 
 ``` js
 vuex: {
-  // getter 函数不能依赖 this
   getters: {
     currentId: state => state.currentId
   }
 },
 computed: {
-  // 但计算属性可以通过 this 引用组件实例
   isCurrent () {
     return this.id === this.currentId
   }
@@ -101,7 +99,7 @@ computed: {
 
 ### getter 函数可以返回派生状态
 
-Vuex 状态的 getters 内部其实是计算属性,这就意味着你能够动态(并且高效)地计算派生属性。例如,下面的例子中,我们有一个包含了全部消息的 `messages` 数组,和一个代表用户当前正在浏览的消息索引的 `currentThreadID`。我们想要展示给用户一个根据当前索引过滤后的消息列表:
+Vuex 状态的 getters 内部其实就是计算属性,这就意味着你能够以响应式的方式(并且更高效)地计算派生属性。举个例子,比如我们有一个包含全部消息的 `messages` 数组,和一个代表用户当前打开帖子的 `currentThreadID` 索引。而我们想仅向用户显示属于当前帖子的信息,一个过滤后的列表:
 
 ``` js
 vuex: {
@@ -115,11 +113,11 @@ vuex: {
 }
 ```
 
-因为 Vue.js 计算属性是自动缓存的,且只有一个动态的依赖改变的时候才会重新计算,所以你不必担心 getter 函数会在每次状态树改变的时候被频繁调用。
+因为 Vue.js 计算属性是自动缓存的,且仅在对应的依赖发生改变时才会重新计算,所以你不必担心 getter 函数会在每次状态变更事件触发时都被频繁的调用。
 
 ### 在多组件中共享 getter 函数
 
-正如你所见,getter 函数 `filteredMessages` 在多个组件中都很有用。这种情况下,在多组件中共享 getter 函数会是很好的办法
+显而易见,`filteredMessages` getter 可能在多个组件中都很有用。这种情况下,让多组件共享相同的 getter 会是个好主意
 
 ``` js
 // getters.js
@@ -143,14 +141,14 @@ export default {
 }
 ```
 
-因为 getter 函数是纯函数,多组件共享的时候 getter 函数可以高效地缓存:当依赖状态改变的时候,在使用 getter 函数的全部组件中只重新计算一次
+因为 getter 函数都是纯函数,被多个组件共享的 getter 被高效地缓存起来了:当依赖状态发生改变的时候,该 getter 也仅仅只重新计算一次,便可供所有组件使用
 
-> Flux 参考: Vuex 的 getter 函数可以大致类比成 Redux 中的 [`mapStateToProps`](https://github.com/rackt/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)。然而, 由于 Vue 的计算可以缓存的计算机制,getter 函数要比 `mapStateToProps` 更加高效,因此更加和 [reselect](https://github.com/reactjs/reselect) 相似
+> 与 Flux 的对比参考:Vuex 的 getter 函数可以大致类比成 Redux 中的 [`mapStateToProps`](https://github.com/rackt/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)。然而, 由于其内部运用了 Vue 的计算属性[记忆化](https://en.wikipedia.org/wiki/Memoization)机制,它要比 `mapStateToProps` 更加高效,且更近似于 ReactJs 的 [reselect](https://github.com/reactjs/reselect)
 
 ### 组件不允许直接修改 store 实例的状态
 
-有一点很重要,需要注意,就是**组件永远都不应该直接修改 Vuex store 实例中的状态**。因为我们想要每个状态的改变都清晰并且可追踪,所有的 Vuex 状态改变必须在 store 实例的 mutation 中进行
+请始终记得非常重要的这点,就是:**组件永远都不应该直接改变 Vuex store 的状态**。因为我们想要让状态的每次改变都很明确且可追踪,Vuex 状态的所有改变都必须在 store 的 mutation handler (变更句柄)中管理
 
-为了保持这个规则,在严格模式([Strict Mode](strict.md))下,如果 store 实例中一个状态在 mutation 外被修改,Vuex 会抛出异常
+为了强化该规则,在开启([严格模式(Strict Mode)](strict.md))时,若有 store 的状态在 mutation 句柄外被修改,Vuex 就会报错
 
-有了这一规则,我们的 Vue 组件现在少了很多职能:这势必让 Vuex 中 store 实例变得只读,组件唯一影响 state 的方法就是触发 **mutations**(我们接下来就讨论)。必要情况下,组件仍然能够拥有和操作自己的状态,但是我们不再在独立的组件中放置任何请求数据或者改变全局状态的逻辑。这些操作全部都集中在 Vuex 相关的文件中,这样能够让大型应用更容易理解和维护。
+现在有了这一规则,我们 Vue 组件的职能就少了很多:他们通过只读的 getter 与 Vuex store 的状态相绑定,组件唯一能影响全局状态的方法就是想办法触发 **mutations**(我们接下来会谈到)。若有必要,组件仍然能够处理和操作本地状态,但是我们不再在单独的组件中放置任何数据请求或全局状态变更的逻辑。这些操作全部都集中于 Vuex 相关的文件中,这样能让大型应用变得更容易理解和维护。

+ 36 - 37
docs/zh-cn/tutorial.md

@@ -1,16 +1,16 @@
-# 教程
+# 简易教程
 
-让我们通过一个简单的实际例子来理解怎样使用 Vuex。这个例子里,我们要实现一个按钮,当你点击它的时候,计数器会加一。
+让我们通过一个简单的实际例子来理解怎样使用 Vuex。这个例子里,我们要实现一个按钮,每点击它一次,计数器加一。
 
 ![End Result](tutorial/result.png)
 
-通过这个简单的例子,我们会解释相应的概念,以及 Vuex 所要解决的问题:如何管理一个包含许多组件的大型应用。假设这个例子使用了以下三个组件:
+我们会通过这个例子解释相应的概念,以及 Vuex 所要解决的问题:如何管理一个包含许多组件的大型应用。我们假定这个例子使用以下三个组件:
 
 ### `components/App.vue`
 
-根组件,它包含了以下两个子组件:
+根组件,它包含了两个另外的子组件:
 
-* `Display` 显示计数器当前的值
+* `Display` 显示当前计数器的值
 * `Increment` 使计数器加一的按钮
 
 ```html
@@ -65,11 +65,11 @@ export default {
 </script>
 ```
 
-### Vuex 要解决的问题
+### 在没有 Vuex 的日子里
 
-* `Increment` 和 `Display` 彼此独立, 不能直接相互传递信息
-* `App` 只能通过事件和广播去整合这两个组件
-* 因为 `App` 需要整合这两个组件,它们无法被重用,形成了紧密的互相依赖。如果需要重构它,容易导致应用的 bug
+* `Increment` 与 `Display` 彼此无法感知到彼此的存在,也无法相互传递消息。是怎样的孤独
+* `App` 将必须通过事件(events)与广播(broadcasts)与其他两个组件进行协调
+* 而 `App` 作为二者之间的协调者,导致这些组件并没法被复用,被迫紧密耦合。调整应用的结构,则可能导致应用崩溃
 
 ### Vuex 的流程
 
@@ -77,11 +77,11 @@ export default {
 
 ![Vuex Flow](tutorial/vuex_flow.png)
 
-仅仅为了增加计数采取这么多步骤似乎有点多余。但是,这些概念的引入使得我们在大型应用里可以有效提高可维护性,在长期来看也可以使得 debug 和做后续改进工作变得更容易。那么接下来我们就用 vuex 来改写我们的代码:
+仅仅为了增加计数而采取这么多步骤显然很多余。但请注意,这些概念的引入是为了构建大型应用,提高可维护性,降低调试与长期维护的难度而设计的。(译注:换言之,这是屠龙刀,拿来杀鸡只是为了让我们好懂)好,那么接下来我们就用 vuex 来进行重构吧!
 
 ### 第一步:加入 store
 
-store 存储应用所需所有数据。所有组件都从 store 中读取数据。在我们开始之前,用 npm 安装 Vuex:
+store 存储应用所需的数据。所有组件都从 store 中读取数据。在我们开始之前,用 npm 安装 Vuex:
 
 ```
 $ npm install --save vuex
@@ -96,27 +96,27 @@ import Vuex from 'vuex'
 // 告诉 vue “使用” vuex
 Vue.use(Vuex)
 
-// 创建一个 object 存储应用启动时的状态
+// 创建一个对象来保存应用启动时的初始状态
 const state = {
-  // TODO: 设置启动状态
+  // TODO: 放置初始状态
 }
 
-// 创建一个 object 存储 mutation 函数
+// 创建一个对象存储一系列我们接下来要写的 mutation 函数
 const mutations = {
-  // TODO: set up our mutations
+  // TODO: 放置我们的状态变更函数
 }
 
-// 通过 new Vuex.Store 结合初始 state 和 mutations,创建 store
-// 这个 store 将和我们的 vue 应用链接起来
+// 整合初始状态和变更函数,我们就得到了我们所需的 store
+// 至此,这个 store 就可以连接到我们的应用中
 export default new Vuex.Store({
   state,
   mutations
 })
 ```
 
-我们需要修改根组件来让我们的应用和 store 建立联系
+我们需要修改根组件来让应用注意到 store 的存在位置
 
-修改 `components/App.vue`,加上 store.
+修改 `components/App.vue`,注入 store。
 
 ```js
 import Display from './Display.vue'
@@ -132,7 +132,7 @@ export default {
 }
 ```
 
-> **提示**: 如果使用 ES6 和 babel 你可以这样写:
+> **提示**:如果使用 ES6 和 babel 你可以这样写:
 >
 >     components: {
 >       Display,
@@ -142,15 +142,14 @@ export default {
 
 ### 第二步:创建 action
 
-action 是给 component 使用的函数。action 函数能够通过 dispatch 对应的 mutation 函数来触发 store 的更新。action 也可以从后端读取数据之后再触发更新
+action 是一种专门用来被 component 调用的函数。action 函数能够通过分发相应的 mutation 函数,来触发对 store 的更新。action 也可以先从 HTTP 后端或 store 中读取其他数据之后再分发更新事件
 
 创建一个新文件 `vuex/actions.js`,然后写入一个函数 `incrementCounter`:
 
-
 ```js
 // action 会收到 store 作为它的第一个参数
-// 在 store 里我们只需要 dispatch (在有些情况下需要 state
-// 我们可以利用 ES6 的解构(destructuring)语法来简化参数的使用
+// 既然我们只对事件的分发(dispatch 对象)感兴趣。(state 也可以作为可选项放入
+// 我们可以利用 ES6 的解构(destructuring)功能来简化对参数的导入
 export const incrementCounter = function ({ dispatch, state }) {
   dispatch('INCREMENT', 1)
 }
@@ -177,13 +176,13 @@ export default {
 </script>
 ```
 
-回顾一下我们刚刚写的一些有趣的东西
+回顾一下我们刚刚添加的内容背后所潜藏的一些有趣的点
 
-1. 我们有了一个新的 object `vuex.actions`,包含着一个新的 action。
-2. 我们没有指定 store, object, state 等等的东西。Vuex 会把它们串联好。
-3. 我们可以使用 `this.increment()` 在任何方法里调用 action。
-4. 我们也可以用 `@click` 参数,像使用普通的 Vue 组件方法一样使用它
-5. 我们给 action 起名叫 `incrementCounter`,但是在使用时我们可以根据需要重新命名
+1. 我们有了一个新对象 `vuex.actions`,包含着新的 action。
+2. 我们没有指定特定的 store, object, state 等等。Vuex 会自动把它们串联好。
+3. 我们可以用 `this.increment()` 在任何方法中调用此 action。
+4. 我们也可以通过 `@click` 参数调用它,与使用其他普通的 Vue 组件方法并无二致
+5. 我们给 action 起名叫 `incrementCounter`,但是在具体使用时我们可以根据需要进行重新命名。
 
 ### 第三步:创建 state 和 mutation
 
@@ -246,11 +245,11 @@ export default {
 
 这里我们又加入了一个新的对象 `vuex.getters`。它将 `counterValue` 绑定到了 `getCount` 这个 getter 函数上。我们给它起了一个新名字来使得这个变量在你的组件里表意更明确。
 
-你可能有点困惑——为什么我们需要用 getter 函数而不是直接从 state 里读取数据。这个概念更多的是一种最佳实践,在大型应用里更加适用。它有这么几种明显的优势:
+你可能有点困惑——为什么我们需要用 getter 函数而不是直接从 state 里读取数据。这个概念更多的是一种最佳实践,在大型应用里更加适用。它有这么几种独特优势:
 
-1. 我们可能需要使用 getter 函数返回经过计算的值(比如总数,平均值等)。
+1. 我们可能需要使用 getter 函数返回经过计算的值(比如总数,平均值等)。
 2. 在大型应用里,很多组件之间可以复用同一个 getter 函数。
-3. 如果这个值的位置改变了(比如从 `store.count` 变成了 `store.counter.value`),你只需要改一个 getter 方法,而不是一堆用到它的组件。
+3. 如果这个值的位置改变了(比如从 `store.count` 变成了 `store.counter.value`),你只需要改一个 getter 方法,而不是一堆组件。
 
 以上便是使用 getter 带来的好处。
 
@@ -258,8 +257,8 @@ export default {
 
 运行一下你的应用,它应该能正常工作了。
 
-要更深入地理解 Vuex,你可以做一个小练习:尝试对这个应用做一些修改。
+要更深入地理解 Vuex,你可以尝试以下挑战,对该应用进行少许修改,权当练习,嗯~
 
-* 加“减一”的按钮。
-* 安装 [VueJS Devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd),尝试使用它提供的 Vuex 工具来观察 mutation 对 state 的改动
-* 加上一个新的组件,让用户可以在文本框中输入要增加的数值。这个会稍有难度,因为在 vuex 架构中表单的处理有些不同。在开始前可以先读一下[表单处理](forms.md)
+* 加一个“减一”的按钮。
+* 安装 [VueJS Devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd),尝试使用它提供的 Vuex 工具来观察 mutation 是如何生效的
+* 添加一个名为 `IncrementAmount ` 的文本框组件,让用户可以输入要增加的数值。这个可能会稍有难度,因为表单在 vuex 中与原生的表现稍有不同。可以读一下[表单处理](forms.md)章节了解更多内容