Sfoglia il codice sorgente

[Feature] middlewares to ignore 'silent' mutation && fixed FSB mutations (#137)

- Added support for 'silent' flag
- Fixed FSB standards https://github.com/acdlite/flux-standard-action
- Updated tests
- Updated docs
- Updated API doc to include 'object style mutation'
Blake Newman 9 anni fa
parent
commit
cbfd5b8ade
4 ha cambiato i file con 94 aggiunte e 6 eliminazioni
  1. 14 1
      docs/en/api.md
  2. 31 0
      docs/en/mutations.md
  3. 4 2
      src/index.js
  4. 45 3
      test/unit/test.js

+ 14 - 1
docs/en/api.md

@@ -79,10 +79,23 @@ const store = new Vuex.Store({ ...options })
 
 
 ### Vuex.Store Instance Methods
 ### Vuex.Store Instance Methods
 
 
-- **dispatch(mutationName: String, ...args)**
+- **dispatch(mutationName: String, ...args) | dispatch(mutation: Object)**
 
 
   Directly dispatch a mutation. This is useful in certain situations are in general you should prefer using actions in application code.
   Directly dispatch a mutation. This is useful in certain situations are in general you should prefer using actions in application code.
 
 
+  *Object-Style Dispatch*
+
+  > requires >=0.6.2
+
+  You can also dispatch mutations using objects:
+
+  ``` js
+  store.dispatch({
+    type: 'INCREMENT',
+    payload: 10
+  })
+  ```
+
 - **watch(pathOrGetter: String|Function, cb: Function, [options: Object])**
 - **watch(pathOrGetter: String|Function, cb: Function, [options: Object])**
 
 
   Watch a path or a getter function's value, and call the callback when the value changes. Accepts an optional options object that takes the same options as Vue's `vm.$watch` method.
   Watch a path or a getter function's value, and call the callback when the value changes. Accepts an optional options object that takes the same options as Vue's `vm.$watch` method.

+ 31 - 0
docs/en/mutations.md

@@ -67,6 +67,37 @@ mutations: {
 }
 }
 ```
 ```
 
 
+### Silent Dispatch
+
+> requires >=0.7.0
+
+In some scenarios you may not want the middlewares to record the state change. Multiple dispatches to the store in a short period or polled do not always need to be tracked. In these situations is may be considered appropriate to silent the mutations. 
+
+*Note:* This should be avoided where necessary. Silent mutations break the contract of all state changes being tracked by the devtool. Use sparingly and where absolutely necessary.
+
+Dispatching without hitting middlewares can be achieved with a `silent` flag.
+
+``` js
+/**
+ * Example: Progress action.
+ * Dispatches often for changes that are not necessary to be tracked
+ **/
+export function start(store, options = {}) {
+  let timer = setInterval(() => {
+    store.dispatch({
+      type: INCREMENT,
+      silent: true,
+      payload: {
+        amount: 1,
+      },
+    });
+    if (store.state.progress === 100) {
+      clearInterval(timer);
+    }
+  }, 10);
+}
+```
+
 ### Mutations Follow Vue's Reactivity Rules
 ### Mutations Follow Vue's Reactivity Rules
 
 
 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:
 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:

+ 4 - 2
src/index.js

@@ -77,9 +77,11 @@ class Store {
    */
    */
 
 
   dispatch (type, ...payload) {
   dispatch (type, ...payload) {
+    let silent = false
     // compatibility for object actions, e.g. FSA
     // compatibility for object actions, e.g. FSA
     if (typeof type === 'object' && type.type && arguments.length === 1) {
     if (typeof type === 'object' && type.type && arguments.length === 1) {
-      payload = [type]
+      payload = [type.payload]
+      if (type.silent) silent = true
       type = type.type
       type = type.type
     }
     }
     const mutation = this._mutations[type]
     const mutation = this._mutations[type]
@@ -93,7 +95,7 @@ class Store {
         mutation(state, ...payload)
         mutation(state, ...payload)
       }
       }
       this._dispatching = false
       this._dispatching = false
-      this._applyMiddlewares(type, payload)
+      if (!silent) this._applyMiddlewares(type, payload)
     } else {
     } else {
       console.warn(`[vuex] Unknown mutation: ${type}`)
       console.warn(`[vuex] Unknown mutation: ${type}`)
     }
     }

+ 45 - 3
test/unit/test.js

@@ -249,6 +249,48 @@ describe('Vuex', () => {
     expect(mutations[0].nextState.a).to.equal(3)
     expect(mutations[0].nextState.a).to.equal(3)
   })
   })
 
 
+  it('middleware should ignore silent mutations', function () {
+    let initState
+    const mutations = []
+    const store = new Vuex.Store({
+      state: {
+        a: 1
+      },
+      mutations: {
+        [TEST] (state, n) {
+          state.a += n
+        }
+      },
+      middlewares: [
+        {
+          onInit (state) {
+            initState = state
+          },
+          onMutation (mut, state) {
+            expect(state).to.equal(store.state)
+            mutations.push(mut)
+          }
+        }
+      ]
+    })
+    expect(initState).to.equal(store.state)
+    store.dispatch(TEST, 1)
+    store.dispatch({
+      type: TEST,
+      payload: 2
+    })
+    store.dispatch({
+      type: TEST,
+      silent: true,
+      payload: 3
+    })
+    expect(mutations.length).to.equal(2)
+    expect(mutations[0].type).to.equal(TEST)
+    expect(mutations[1].type).to.equal(TEST)
+    expect(mutations[0].payload[0]).to.equal(1)
+    expect(mutations[1].payload[0]).to.equal(2)
+  })
+
   it('watch', function (done) {
   it('watch', function (done) {
     const store = new Vuex.Store({
     const store = new Vuex.Store({
       state: {
       state: {
@@ -396,14 +438,14 @@ describe('Vuex', () => {
         a: 1
         a: 1
       },
       },
       mutations: {
       mutations: {
-        [TEST] (state, action) {
-          state.a += action.by
+        [TEST] (state, amount) {
+          state.a += amount
         }
         }
       }
       }
     })
     })
     store.dispatch({
     store.dispatch({
       type: TEST,
       type: TEST,
-      by: 2
+      payload: 2
     })
     })
     expect(store.state.a).to.equal(3)
     expect(store.state.a).to.equal(3)
   })
   })