Browse Source

[docs] state/mutations

Evan You 9 năm trước cách đây
mục cha
commit
1e592a890c
2 tập tin đã thay đổi với 34 bổ sung7 xóa
  1. 19 5
      docs/en/mutations.md
  2. 15 2
      docs/en/state.md

+ 19 - 5
docs/en/mutations.md

@@ -1,6 +1,6 @@
 # Mutations
 
-Vuex mutations are essentially events: each mutation has a **name** and a **handler**. The handler function always gets the entire state tree as the first argument:
+Vuex mutations are essentially events: each mutation has a **name** and a **handler**. The handler function will receive the state as the first argument:
 
 ``` js
 import Vuex from 'vuex'
@@ -18,7 +18,7 @@ const store = new Vuex.Store({
 })
 ```
 
-Using all caps for mutation names is just a convention to make it easier to differentiate them from actions.
+Using all caps for mutation names is just a convention to make it easier to differentiate them from plain functions.
 
 You cannot directly call a mutation handler. The options here is more like event registration: "When an `INCREMENT` event is dispatched, call this handler." To invoke a mutation handler, you need to dispatch a mutation event:
 
@@ -89,8 +89,22 @@ const store = new Vuex.Store({
 
 Whether to use constants is largely a preference - it can be helpful in large projects with many developers, but it's totally optional if you don't like them.
 
-### On to Actions
+### Mutations Must Be Synchronous
+
+One important rule to remember is that **mutation handler functions must be synchronous**. Why? Consider the following example:
 
-So far, we've triggering mutations by manually calling `store.dispatch`. This is a viable approach, but in practice, we will rarely do this in our component code. Most of the time we will be calling [actions](actions.md), which can encapsulate more complex logic such as async data fetching.
+``` js
+mutations: {
+  SOME_MUTATION (state) {
+    api.callAsyncMethod(() => {
+      state.count++
+    })
+  }
+}
+```
+
+Now imagine we are debugging the app and looking at our mutation logs. For every mutation logged, we want to be able to compare snapshots of the state *before* and *after* the mutation. However, the asynchronous callback inside the example mutation above makes that impossible: the callback is not called yet when the mutation is dispatched, and we do not know when the callback will actually be called. Any state mutation performed in the callback is essentially un-trackable!
+
+### On to Actions
 
-Also, one important rule to remember: all mutation handlers must be **synchronous**. Any async operations belong in actions.
+Asynchronicity combined with state mutation can make your program very hard to reason about. For example, when you call two methods both with async callbacks that mutate the state, how do you know when they are called and which callback was called first? This is exactly why we want to separate the two concepts. In Vuex, we perform all state mutations in a synchronous manner. We will perform all asynchronous operations inside [Actions](actions.md).

+ 15 - 2
docs/en/state.md

@@ -8,7 +8,20 @@ The single state tree does not conflict with modularity - in later chapters we w
 
 ### Getting Vuex State into Vue Components
 
-So how do we display state inside the store in our Vue components? Here's how:
+So how do we display state inside the store in our Vue components? Since Vuex stores are reactive, the simplest way to "retrieve" state from it is simply returning some store state from within a [computed property](http://vuejs.org/guide/computed.html):
+
+``` js
+// in a Vue component definition
+computed: {
+  count: function () {
+    return store.state.count
+  }
+}
+```
+
+Whenever `store.state.count` changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.
+
+However, this pattern causes the component to rely on the global store singleton. This makes it harder to test the component, and also makes it difficult to run multiple instances of the app using the same set of components. Ideally, we want to "inject" the store into child components from the root component. Here's how to do it:
 
 1. Install Vuex and connect your root component to the store:
 
@@ -52,7 +65,7 @@ So how do we display state inside the store in our Vue components? Here's how:
   }
   ```
 
-  Note the special `vuex` option block. This is where we specify what state the component will be using from the store. For each property name, we specify a function which receives the entire state tree as the only argument, and then selects and returns a part of the state, or even computes derived state. The returned result will be set on the component using the property name.
+  Note the special `vuex` option block. This is where we specify what state the component will be using from the store. For each property name, we specify a getter function which receives the entire state tree as the only argument, and then selects and returns a part of the state, or a computed value derived from the state. The returned result will be set on the component using the property name, just like a computed property.
 
   In a lot of cases, the "getter" function can be very succinct using ES2015 arrow functions: