Skip to content

Commit

Permalink
[Feature] middlewares to ignore 'silent' mutation && fixed FSB mutati…
Browse files Browse the repository at this point in the history
…ons (vuejs#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'
  • Loading branch information
blake-newman authored and yyx990803 committed Apr 8, 2016
1 parent e4dd092 commit cbfd5b8
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 6 deletions.
15 changes: 14 additions & 1 deletion docs/en/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,23 @@ const store = new Vuex.Store({ ...options })
### 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.
*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 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.
Expand Down
31 changes: 31 additions & 0 deletions docs/en/mutations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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:
Expand Down
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ class Store {
*/

dispatch (type, ...payload) {
let silent = false
// compatibility for object actions, e.g. FSA
if (typeof type === 'object' && type.type && arguments.length === 1) {
payload = [type]
payload = [type.payload]
if (type.silent) silent = true
type = type.type
}
const mutation = this._mutations[type]
Expand All @@ -93,7 +95,7 @@ class Store {
mutation(state, ...payload)
}
this._dispatching = false
this._applyMiddlewares(type, payload)
if (!silent) this._applyMiddlewares(type, payload)
} else {
console.warn(`[vuex] Unknown mutation: ${type}`)
}
Expand Down
48 changes: 45 additions & 3 deletions test/unit/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,48 @@ describe('Vuex', () => {
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) {
const store = new Vuex.Store({
state: {
Expand Down Expand Up @@ -396,14 +438,14 @@ describe('Vuex', () => {
a: 1
},
mutations: {
[TEST] (state, action) {
state.a += action.by
[TEST] (state, amount) {
state.a += amount
}
}
})
store.dispatch({
type: TEST,
by: 2
payload: 2
})
expect(store.state.a).to.equal(3)
})
Expand Down

0 comments on commit cbfd5b8

Please sign in to comment.