Today, xiaobian will continue to study and discuss Vuex with you. Let’s continue to explore other features of Vuex
Vuex provides Mutation mode for uniform modification, and State is used as the first parameter. Just like that. You can also follow my wechat public number, Snail Quanzhan.
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// Change the state
state.count++
}
}
})
Copy the code
To trigger this function, this is all you need
store.commit('increment')
Copy the code
And you can also, when you submit, you can pass in an extra parameter, Payload, like this
/ /... mutations: {
increment (state, n) {
state.count += n
}}
Copy the code
store.commit('increment'.10)
Copy the code
In fact, when we used the second parameter of Mutation, it was more common to pass an object. Meanwhile, a larger amount of data information could also be passed, just like this
/ /... mutations: { increment (state, payload) { state.count += payload.amount }}Copy the code
store.commit('increment', { amount: 10})
Copy the code
Also, an “object submission style” was proposed, with Type as the key of the submitted object, corresponding to the corresponding method in the trigger Mutation, like this
store.commit({ type: 'increment'.amount: 10})
Copy the code
mutations: { increment (state, payload) { state.count += payload.amount }}
Copy the code
Js has made a number of extensions to its new syntax for objects, including the extension operator, which can merge values of the same attributes. Similarly, some Linux configuration files use similar ideas.
state.obj = { ... state.obj,newProp: 123 }
Copy the code
In real projects, it is easy to make mistakes with strings. In previous articles, the editor provided two solutions, one is to use es6 Symbol to implement, and the other is to define constants to implement, which are also reflected in Vuex.
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
Copy the code
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state: {... },mutations: {
// We can use ES2015 style computed attribute naming to use a constant as the function name
[SOME_MUTATION] (state) { // mutate state }}})Copy the code
For Mutation, a shorthand method is also provided in the component. Similar to mapGetters, mapMutations is provided.
import { mapMutations } from 'vuex'
export default {
/ /... methods: {. mapMutations(['increment'.// Map 'this.increment()' to
`this.$store.commit('increment')`
// 'mapMutations' also supports payloads:
'incrementBy'
// Map 'this.incrementBy(amount)' to 'this. codestore.com MIT ('incrementBy', amount)']),. mapMutations({add: 'increment'
// Map 'this.add()' to 'this.store.mit ('increment')'}}})Copy the code
It is also worth noting that Mutation must be a synchronization function. Why is that? Please refer to the following example:
mutations: {
someMutation (state) {
api.callAsyncMethod(() = > {
state.count++
})
}}
Copy the code
Now imagine that we are debugging an app and looking at the mutation log in devtool. Each mutation is recorded, and DevTools needs to capture a snapshot of the previous state and the next state. However, the callback in the asynchronous function in mutation in the example above made this impossible: Because the callback had not yet been called when mutation was triggered, DevTools did not know when the callback was actually called — essentially any state change made in the callback was untraceable. Actions (Vuex) : Actions (Vuex) : Actions (Vuex) : Actions (Vuex) : Actions (Vuex) : Actions (Vuex) : Actions (Vuex)
- The Action commits mutation instead of a direct state change;
- Actions can contain any asynchronous operation.
Let’s start with a simple action
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')}}})Copy the code
When we distribute the action, that’s all we need to do,
store.dispatch('increment')
Copy the code
Also, within actions, asynchronous operations are allowed, which is different from mutation, as shown here
actions: {
incrementAsync ({ commit }) {
setTimeout(() = > {
commit('increment')},1000)}}Copy the code
Action also supports the same payload and object distribution
// Distribute in payload form
store.dispatch('incrementAsync', { amount: 10})
// Distribute as objects
store.dispatch({ type: 'incrementAsync'.amount: 10})
Copy the code
In components, shorthand is also supported
import { mapActions } from 'vuex'
export default {
/ /... methods: {. mapActions(['increment'.// Map 'this.increment()' to 'this.$store.dispatch('increment')'
// 'mapActions' also supports payloads:
'incrementBy' // Map 'this.incrementBy(amount)' to 'this.$store.dispatch('incrementBy', amount)'
]),
...mapActions({
add: 'increment' // Map 'this.add()' to 'this.$store.dispatch('increment')'}}})Copy the code
Similarly, when we use actions, we can combine them with Promise features and async and await to write code that is more maintainable and more comfortable to look at, like this
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
commit('someMutation')
resolve()
}, 1000)}}}Copy the code
store.dispatch('actionA').then(() = > { / /... })
Copy the code
actions: { // ...
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() = > {
commit('someOtherMutation')}}}Copy the code
Finally, if we use async/await (open new window), we can compose actions as follows:
// Suppose getData() and getOtherData() return a Promise
actions: {
async actionA ({ commit }) {
commit('gotData'.await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // Wait for actionA to complete
commit('gotOtherData'.await getOtherData())
}}
Copy the code
Reference: vuex.vuejs.org/zh/