Browse Source

update docs

Evan You 9 years ago
parent
commit
ec4a2fe129

+ 16 - 18
docs/en/actions.md

@@ -13,7 +13,7 @@ Therefore, we usually perform API calls to data endpoints inside actions, and hi
 It is common that an action simply triggers a single mutation. Vuex provides a shorthand for defining such actions:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   state: {
     count: 1
   },
@@ -33,20 +33,20 @@ const vuex = new Vuex({
 Now when we call the action:
 
 ``` js
-vuex.actions.increment(1)
+store.actions.increment(1)
 ```
 
 It simply calls the following for us:
 
 ``` js
-vuex.dispatch('INCREMENT', 1)
+store.dispatch('INCREMENT', 1)
 ```
 
 Note any arguments passed to the action is also passed along to the mutation handler.
 
-### Thunk Actions
+### Normal Actions
 
-How about actions that involve logic depending on current state, or that need async operations? We can define these actions as **thunks** - essentially functions that return another function:
+For actions that involve logic depending on current state, or that need async operations, we define them as functions. Action functions always get the store calling it as the first argument:
 
 ``` js
 const vuex = new Vuex({
@@ -59,23 +59,21 @@ const vuex = new Vuex({
     }
   },
   actions: {
-    incrementIfOdd: function (x) {
-      return function (dispatch, state) {
-        if ((state.count + 1) % 2 === 0) {
-          dispatch('INCREMENT', x)
-        }
+    incrementIfOdd: (store, x) => {
+      if ((store.state.count + 1) % 2 === 0) {
+        store.dispatch('INCREMENT', x)
       }
     }
   }
 })
 ```
 
-Here, the outer function receives the arguments passed when calling the action. Then, it returns a function that gets 2 arguments: first is the `dispatch` function, and the second being the `state`. We are using ES5 syntax here to make things easier to understand. With ES2015 arrow functions we can "prettify" the above to the following:
+It is common to use ES6 argument destructuring to make the function body less verbose (here the `dispatch` function is pre-bound to the store instance so we don't have to call it as a method):
 
 ``` js
 // ...
 actions: {
-  incrementIfOdd: x => (dispatch, state) => {
+  incrementIfOdd: ({ dispatch, state }, x) => {
     if ((state.count + 1) % 2 === 0) {
       dispatch('INCREMENT', x)
     }
@@ -91,20 +89,20 @@ actions: {
 }
 // ... equivalent to:
 actions: {
-  increment: (...args) => dispatch => dispatch('INCREMENT', ...args)
+  increment: ({ dispatch }, ...payload) => {
+    dispatch('INCREMENT', ...payload)
+  }
 }
 ```
 
-Why don't we just define the actions as simple functions that directly access `vuex.state` and `vuex.dispatch`? The reason is that such usage couples the action functions to the specific vuex instance. By using the thunk syntax, our actions only depend on function arguments and nothing else - this important characteristic makes them easy to test and hot-reloadable!
-
 ### Async Actions
 
-We can use the same thunk syntax for defining async actions:
+We can use the same syntax for defining async actions:
 
 ``` js
 // ...
 actions: {
-  incrementAsync: x => dispatch => {
+  incrementAsync: ({ dispatch }, x) => {
     setTimeout(() => {
       dispatch('INCREMENT', x)
     }, 1000)
@@ -117,7 +115,7 @@ A more practical example is when checking out a shopping cart - we may need to t
 ``` js
 // ...
 actions: {
-  checkout: products => (dispatch, state) => {
+  checkout: ({ dispatch, state }, products) => {
     // save the current in cart items
     const savedCartItems = [...state.cart.added]
     // send out checkout request, and optimistically

+ 9 - 9
docs/en/api.md

@@ -1,20 +1,20 @@
 # API Reference
 
-### Constructor
+### Vuex.Store
 
 ``` js
 import Vuex from 'vuex'
 
-const vuex = new Vuex({ ...options })
+const vuex = new Vuex.Store({ ...options })
 ```
 
-### Constructor Options
+### Vuex.Store Constructor Options
 
 - **state**
   
   - type: `Object`
 
-    The root state object for the Vuex instance.
+    The root state object for the Vuex store.
 
     [Details](state.md)
 
@@ -35,9 +35,9 @@ const vuex = new Vuex({ ...options })
     An object where each entry's key is the action name and the value is either
 
     1. A mutation name string; or
-    2. A thunk action creator function.
+    2. A function which will receive the store as the first argument, followed by additional payload arguments.
 
-    Vuex will process these entries and create the actual callable action functions and expose them on the `actions` property of the instance.
+    Vuex will process these entries and create the actual callable action functions and expose them on the `actions` property of the store.
 
     If passing in an Array of Objects, these objects will be automatically merged together into one final object.
 
@@ -64,11 +64,11 @@ const vuex = new Vuex({ ...options })
   - type: `Boolean`
   - default: `false`
 
-    Force the Vuex instance into strict mode. In strict mode any mutations to Vuex state outside of mutation handlers will throw en Error.
+    Force the Vuex store into strict mode. In strict mode any mutations to Vuex state outside of mutation handlers will throw en Error.
 
     [Details](strict.md)
 
-### Instance Properties
+### Vuex.Store Instance Properties
 
 - **state**
 
@@ -82,7 +82,7 @@ const vuex = new Vuex({ ...options })
 
     The callable action functions.
 
-### Instance Methods
+### Vuex.Store Instance Methods
 
 - **dispatch(mutationName: String, ...args)**
 

+ 5 - 8
docs/en/concepts.md

@@ -1,8 +1,6 @@
 # Core Concepts
 
-Similar to Vue itself, Vuex exposes a single `Vuex` constructor. You can use it to create **Vuex instances**. In most cases, you only need one Vuex instance for an app. You can think of a Vuex instance as an "enhanced store" that holds your app state.
-
-Each Vuex instance consists of three types of "ingredients":
+You can use the `Vuex.Store` constructor to create Vuex stores. Each Vuex store consists of three types of "ingredients":
 
 - **State**: A plain object representing the application state.
 
@@ -14,21 +12,20 @@ Why do we differentiate between *mutations* and *actions*, rather then just simp
 
 > If you are familiar with Flux, note there's a term/concept difference here: Vuex mutations are the equivalent of Flux **actions**, while Vuex actions are equivalent to Flux **action creators**.
 
-### Creating a Vuex Instance
+### Creating a Vuex Store
 
 > **NOTE:** We will be using ES2015 syntax for code examples for the rest of the docs. If you haven't picked it up, [you should](https://babeljs.io/docs/learn-es2015/)! The doc also assumes you are already familiar with the concepts discussed in [Building Large-Scale Apps with Vue.js](http://vuejs.org/guide/application.html).
 
-Creating a Vuex instance is pretty straightforward - just put the aforementioned ingredients together:
+Creating a Vuex store is pretty straightforward - just put the aforementioned ingredients together:
 
 ``` js
 import Vuex from 'vuex'
 
-const vuex = new Vuex({
+const store = new Vuex.Store({
   state: { ... },
   actions: { ... },
   mutations: { ... }
 })
 ```
 
-Once created, you can access the state via `vuex.state`, and the actions via `vuex.actions`. You cannot directly access the mutation functions - they can only be triggered by actions or calling `vuex.dispatch()`. We will discuss each concept in more details next.
-
+Once created, you can access the state via `store.state`, and the actions via `store.actions`. You cannot directly access the mutation functions - they can only be triggered by actions or calling `store.dispatch()`. We will discuss each concept in more details next.

+ 8 - 8
docs/en/data-flow.md

@@ -5,7 +5,7 @@ Let's build a simple counter app with Vuex to get a better understanding of the
 ### Setup
 
 ``` js
-// vuex.js
+// store.js
 import Vue from 'vue'
 import Vuex from 'vuex'
 
@@ -42,10 +42,10 @@ const actions = {
 }
 ```
 
-### Create a Vuex Instance
+### Create a Vuex Store
 
 ``` js
-export default new Vuex({
+export default new Vuex.Store({
   state,
   mutations,
   actions
@@ -67,23 +67,23 @@ export default new Vuex({
 **Script**
 
 ``` js
-import vuex from './vuex.js'
+import store from './store.js'
 
 export default {
   computed: {
     // bind to state using computed properties
     count () {
-      return vuex.state.count
+      return store.state.count
     }
   },
   methods: {
-    increment: vuex.actions.increment,
-    decrement: vuex.actions.decrement
+    increment: store.actions.increment,
+    decrement: store.actions.decrement
   }
 }
 ```
 
-Here you will notice the component itself is extremely simple: it simply displays some state from the Vuex instance (not even owning its own data), and calls some vuex actions on user input events.
+Here you will notice the component itself is extremely simple: it simply displays some state from the Vuex store (not even owning its own data), and calls some store actions on user input events.
 
 You will also notice the data flow is unidirectional, as it should be in Flux:
 

+ 3 - 3
docs/en/forms.md

@@ -6,7 +6,7 @@ When using Vuex in strict mode, it could be a bit tricky to use `v-model` on a p
 <input v-model="obj.message">
 ```
 
-Assuming `obj` is a computed property that returns an Object from Vuex state, the `v-model` here will attempt to directly mutate `obj.message` when the user types in the input. In strict mode, this will result in en error because the mutation is not performed inside an explicit Vuex mutation handler.
+Assuming `obj` is a computed property that returns an Object from the store, the `v-model` here will attempt to directly mutate `obj.message` when the user types in the input. In strict mode, this will result in en error because the mutation is not performed inside an explicit Vuex mutation handler.
 
 The "Vuex way" to deal with it is binding the `<input>`'s value and call an action on the `input` or `change` event:
 
@@ -17,7 +17,7 @@ The "Vuex way" to deal with it is binding the `<input>`'s value and call an acti
 // ...
 methods: {
   updateMessage: function (e) {
-    vuex.actions.updateMessage(e.target.value)
+    store.actions.updateMessage(e.target.value)
   }
 }
 ```
@@ -33,4 +33,4 @@ mutations: {
 }
 ```
 
-Admittedly, this is quite a bit more verbose than a simple `v-model`, but such is the cost of making state changes explicit and track-able. At the same time, do note that Vuex doesn't demand putting all your state inside a Vuex instance - if you do not wish to track the mutations for form interactions at all, you can simply keep the form state outside of Vuex as component local state, which allows you to freely leverage `v-model`.
+Admittedly, this is quite a bit more verbose than a simple `v-model`, but such is the cost of making state changes explicit and track-able. At the same time, do note that Vuex doesn't demand putting all your state inside a Vuex store - if you do not wish to track the mutations for form interactions at all, you can simply keep the form state outside of Vuex as component local state, which allows you to freely leverage `v-model`.

+ 3 - 3
docs/en/hot-reload.md

@@ -2,11 +2,11 @@
 
 Vuex supports hot-reloading actions and mutations during development, using Webpack's [Hot Module Replacement API](https://webpack.github.io/docs/hot-module-replacement.html). You can also use it in Browserify with the [browserify-hmr](https://github.com/AgentME/browserify-hmr/) plugin.
 
-It's as simple as calling `vuex.hotUpdate()` with the new actions and mutations:
+It's as simple as calling `store.hotUpdate()` with the new actions and mutations:
 
 ``` js
 // ...
-const vuex = new Vuex({
+const store = new Vuex.Store({
   state,
   actions,
   mutations
@@ -20,7 +20,7 @@ if (module.hot) {
     const newActions = require('./actions').default
     const newMutations = require('./mutations').default
     // swap in the new actions and mutations
-    vuex.hotUpdate({
+    store.hotUpdate({
       actions: newActions,
       mutations: newMutations
     })

+ 4 - 4
docs/en/middlewares.md

@@ -1,6 +1,6 @@
 # Middlewares
 
-Vuex instances accept the `middlewares` option that exposes hooks for each mutation (Note this is completely unrelated to Redux middlewares). A Vuex middleware is simply an object that implements some hook functions:
+Vuex stores accept the `middlewares` option that exposes hooks for each mutation (Note this is completely unrelated to Redux middlewares). A Vuex middleware is simply an object that implements some hook functions:
 
 ``` js
 const myMiddleware = {
@@ -17,7 +17,7 @@ const myMiddleware = {
 And can be used like this:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   // ...
   middlewares: [myMiddleware]
 })
@@ -40,7 +40,7 @@ const myMiddlewareWithSnapshot = {
 **Middlewares that take state snapshots should be used only during development.** When using Webpack or Browserify, we can let our build tools handle that for us:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   // ...
   middlewares: process.env.NODE_ENV !== 'production'
     ? [myMiddlewareWithSnapshot]
@@ -55,7 +55,7 @@ The middleware will be used by default. For production, use the build setup desc
 Vuex comes with a logger middleware for common debugging usage:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   middlewares: [Vuex.createLogger()]
 })
 ```

+ 8 - 8
docs/en/mutations.md

@@ -5,7 +5,7 @@ Vuex mutations are essentially events: each mutation has a **name** and a **hand
 ``` js
 import Vuex from 'vuex'
 
-const vuex = new Vuex({
+const store = new Vuex.Store({
   state: {
     count: 1
   },
@@ -23,7 +23,7 @@ Using all caps for mutation names is just a convention to make it easier to diff
 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:
 
 ``` js
-vuex.dispatch('INCREMENT')
+store.dispatch('INCREMENT')
 ```
 
 ### Dispatch with Arguments
@@ -39,16 +39,16 @@ mutations: {
 }
 ```
 ``` js
-vuex.dispatch('INCREMENT', 10)
+store.dispatch('INCREMENT', 10)
 ```
 
 Here `10` will be passed to the mutation handler as the second argument following `state`. Same for any additional arguments. These arguments are called the **payload** for the given mutation.
 
 ### Mutations Follow Vue's Reactivity Rules
 
-Since Vuex's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue:
+Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue:
 
-1. Prefer initializing your Vuex initial state with all desired fields upfront.
+1. Prefer initializing your store's initial state with all desired fields upfront.
 2. When adding new properties to an Object, you should either use `Vue.set(obj, 'newProp', 123)`, or replace that Object with a fresh one, e.g. `state.obj = { ...state.obj, newProp: 123 }` (Using stage-2 [object spread syntax](https://github.com/sebmarkbage/ecmascript-rest-spread) here).
 
 ### Using Constants for Mutation Names
@@ -61,11 +61,11 @@ export const SOME_MUTATION = 'SOME_MUTATION'
 ```
 
 ``` js
-// vuex.js
+// store.js
 import Vuex from 'vuex'
 import { SOME_MUTATION } from './mutation-types'
 
-const vuex = new Vuex({
+const store = new Vuex.Store({
   state: { ... },
   actions: { ... },
   mutations: {
@@ -82,6 +82,6 @@ Whether to use constants is largely a preference - it can be helpful in large pr
 
 ### On to Actions
 
-Manually calling `vuex.dispatch` is possible, 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.
+Manually calling `store.dispatch` is possible, 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.
 
 Also, one important rule to remember: all mutation handlers must be **synchronous**. Any async operations belong in actions.

+ 11 - 11
docs/en/state.md

@@ -8,45 +8,45 @@ The single state tree does not conflict with modularity - in later chapters we w
 
 ### Getting Vuex State into Vue Components
 
-Similar to `data` objects passed to Vue instances, the `state` object, once passed into a Vuex instance, becomes reactive powered by [Vue's reactivity system](http://vuejs.org/guide/reactivity.html). This means binding Vuex state to Vue components is as simple as returning it from within a computed property:
+Similar to `data` objects passed to Vue instances, the `state` object, once passed into a Vuex store, becomes reactive powered by [Vue's reactivity system](http://vuejs.org/guide/reactivity.html). This means binding Vuex state to Vue components is as simple as returning it from within a computed property:
 
 ``` js
 // inside a Vue component module
 
-// import a vuex instance
-import vuex from './vuex'
+// import a vuex store
+import store from './store'
 
 export default {
   computed: {
     message () {
-      return vuex.state.message
+      return store.state.message
     }
   }
 }
 ```
 
-There's no need to worry about setting up and tearing down listeners, or "connecting" the component to a store. The only thing to remember is that you should **always reference state via `vuex.state.xxx` inside your computed properties**. Do not cache the reference to a piece of state outside computed properties.
+There's no need to worry about setting up and tearing down listeners, or "connecting" the component to a store. The only thing to remember is that you should **always reference state via `store.state.xxx` inside your computed properties**. Do not cache the reference to a piece of state outside computed properties.
 
 > Flux reference: this can be roughly compared to [`mapStateToProps`](https://github.com/rackt/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options) in Redux and [getters](https://optimizely.github.io/nuclear-js/docs/04-getters.html) in NuclearJS.
 
-Why don't we just use `data` to bind to vuex state? Consider the following example:
+Why don't we just use `data` to bind to the state? Consider the following example:
 
 ``` js
 export default {
   data () {
     return {
-      message: vuex.state.message
+      message: store.state.message
     }
   }
 }
 ```
 
-Because the `data` function does not track any reactive dependencies, we are only getting a static reference to `vuex.state.message`. When the Vuex state is mutated later, the component has no idea that something has changed. In comparison, computed properties track all reactive dependencies when they are evaluated, so they reactively re-evaluate when the related vuex state mutates.
+Because the `data` function does not track any reactive dependencies, we are only getting a static reference to `store.state.message`. When the state is mutated later, the component has no idea that something has changed. In comparison, computed properties track all reactive dependencies when they are evaluated, so they reactively re-evaluate when the related state is mutated.
 
 ### Components Are Not Allowed to Directly Mutate State
 
-Using read-only computed properties has another benefit in that it helps emphasizing the rule that **components should never directly mutate Vuex state**. Because we want every state mutation to be explicit and trackable, all vuex state mutations must be conducted inside vuex mutation handlers.
+Using read-only computed properties has another benefit in that it helps emphasizing the rule that **components should never directly mutate Vuex store state**. Because we want every state mutation to be explicit and trackable, all vuex store state mutations must be conducted inside the store's mutation handlers.
 
-To help enforce this rule, when in [Strict Mode](strict.md), if Vuex state is mutated outside of mutation handlers, Vuex will throw an error.
+To help enforce this rule, when in [Strict Mode](strict.md), if a store's state is mutated outside of its mutation handlers, Vuex will throw an error.
 
-With this rule in place, our Vue components now hold a lot less responsibility: they connect to Vuex state via read-only computed properties, and the only way for them to affect Vuex state is by calling **actions**, which in turn trigger **mutations**. They can still possess and operate on their local state if necessary, but we no longer put any data-fetching or global-state-mutating logic inside individual components.
+With this rule in place, our Vue components now hold a lot less responsibility: they are bound to Vuex store state via read-only computed properties, and the only way for them to affect the state is by calling **actions**, which in turn trigger **mutations**. They can still possess and operate on their local state if necessary, but we no longer put any data-fetching or global-state-mutating logic inside individual components.

+ 3 - 3
docs/en/strict.md

@@ -1,9 +1,9 @@
 # Strict Mode
 
-To enable strict mode, simply pass in `strict: true` when creating the Vuex instance:
+To enable strict mode, simply pass in `strict: true` when creating a Vuex store:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   // ...
   strict: true
 })
@@ -18,7 +18,7 @@ In strict mode, whenever Vuex state is mutated outside of mutation handlers, an
 Similar to middlewares, we can let the build tools handle that:
 
 ``` js
-const vuex = new Vuex({
+const store = new Vuex.Store({
   // ...
   strict: process.env.NODE_ENV !== 'production'
 })

+ 9 - 9
docs/en/structure.md

@@ -7,7 +7,7 @@ Vuex doesn't really restrict how you structure your code. Rather, it enforces a
 3. Mutations must be synchronous, and the only side effects they produce should be state mutation.
 4. All asynchronous logic such as data fetching should be performed in actions.
 
-The nice thing about Vuex actions and mutations is that **they are just functions with no external dependencies**. As long as you follow these rules, it's up to you how to structure your project. The simplest Vuex instance can even be declared [in a single file](https://github.com/vuejs/vuex/blob/master/examples/counter/vuex.js)! However, this is unlikely to suffice for any serious project, so here are some recommended structures depending on the scale of your app.
+The nice thing about Vuex actions and mutations is that **they are just functions**. As long as you follow these rules, it's up to you how to structure your project. The simplest Vuex instance can even be declared [in a single file](https://github.com/vuejs/vuex/blob/master/examples/counter/vuex.js)! However, this is unlikely to suffice for any serious project, so here are some recommended structures depending on the scale of your app.
 
 ### Simple Project
 
@@ -20,8 +20,8 @@ For a simple project, we can simply separate **actions** and **mutations** into
 ├── components
 │   ├── App.vue
 │   └── ...
-└── vuex
-    ├── index.js     # exports the vuex instance
+└── store
+    ├── index.js     # exports the vuex store
     ├── actions.js   # exports all actions
     └── mutations.js # exports all mutations
 ```
@@ -40,7 +40,7 @@ For any non-trivial app, we probably want to further split Vuex-related code int
 ├── components
 │   ├── App.vue
 │   └── ...
-└── vuex
+└── store
     ├── actions.js # exports all actions
     ├── index.js
     ├── modules
@@ -73,7 +73,7 @@ export const productsMutations = {
 }
 ```
 
-And in `vuex/index.js`, we "assemble" multiple modules together to create the Vuex instance:
+And in `store/index.js`, we "assemble" multiple modules together to create the Vuex instance:
 
 ``` js
 import Vue from 'vue'
@@ -85,7 +85,7 @@ import { productsInitialState, productsMutations } from './modules/products'
 
 Vue.use(Vuex)
 
-export default new Vuex({
+export default new Vuex.Store({
   // ...
   // combine sub-trees into root state
   state: {
@@ -110,11 +110,11 @@ In large projects, it's possible that multiple components will need the same com
 
 ``` js
 // getters.js
-import vuex from './vuex'
+import store from './store'
 
 export function filteredTodos () {
-  return vuex.state.messages.filter(message => {
-    return message.threadID === vuex.state.currentThreadID
+  return store.state.messages.filter(message => {
+    return message.threadID === store.state.currentThreadID
   })
 }
 ```

+ 9 - 4
docs/en/testing.md

@@ -34,7 +34,7 @@ Example testing an async action:
 // actions.js
 import shop from '../api/shop'
 
-export const getAllProducts = () => dispatch => {
+export const getAllProducts = ({ dispatch }) => {
   dispatch('REQUEST_PRODUCTS')
   shop.getProducts(products => {
     dispatch('RECEIVE_PRODUCTS', products)
@@ -65,7 +65,8 @@ const actions = actionsInjector({
 // helper for testing action with expected mutations
 const testAction = (action, state, expectedMutations, done) => {
   let count = 0
-  const mockedDispatch = (name, payload) => {
+  // mock dispatch
+  const dispatch = (name, payload) => {
     const mutation = expectedMutations[count]
     expect(mutation.name).to.equal(name)
     if (payload) {
@@ -76,12 +77,16 @@ const testAction = (action, state, expectedMutations, done) => {
       done()
     }
   }
-  action(mockedDispatch, state)
+  // call the action with mocked store
+  action({
+    dispatch,
+    state
+  })
 }
 
 describe('actions', () => {
   it('getAllProducts', done => {
-    testAction(actions.getAllProducts(), {}, [
+    testAction(actions.getAllProducts, {}, [
       { name: 'REQUEST_PRODUCTS' },
       { name: 'RECEIVE_PRODUCTS', payload: [ /* mocked response */ ] }
     ], done)