This article is basically rom Violation of Vuex, using easy-to-understand text, also deletes the original content.
If you don't mind the above statement, you can continue to read this article and hope it will help you.
To learn a new technology, you must be clear about the two W's,'What&Why'.
"What is XX?"Why use XX, or what is the benefit of XX?" Finally, how does XX work?
What is Vuex?
Vuex is a Redux-like state manager that manages the state of all components of a Vue.
Why use Vuex?
When you plan to develop a large single-page application (SPA), multiple view components will depend on the same state, and behavior from different views will need to change the same state.
When you encounter these situations, you should consider using Vuex, which extracts the shared state of components and manages them as a global singleton mode.This way, wherever you change the state, components that use it will be notified to make changes accordingly.
The following explains how to use Vuex.
The simplest Vuex example
This article doesn't cover how to install Vuex, just walk through the code.
import Vue from 'vue';
import Vuex form 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
This is the simplest Vuex, and each Vuex application is a store that contains shared state states and mutations of methods (temporarily called methods) that change state in components.
It is important to note that the state of stores can only be changed by mutations, not by store.state.count. = 5; change directly (actually can change, not recommended, state is not synchronized without mutations).
Use the store.commit method to trigger mutations to change state:
store.commit('increment');
console.log(store.state.count) // 1
A simple Vuex application is implemented.
Using Vuex in a Vue component
If you want Vuex status updates, the corresponding Vue components will also be updated. The easiest way to do this is to get the state from Vuex computed
// Counter Component
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count;
}
}
}
The example above is to directly manipulate the global state store.state.count, so each component that uses this Vuex is introduced.To address this, Vuex provides a mechanism to inject state from the root component into each subcomponent through the store option.
// Root Component
import Vue from 'vue';
import Vuex form 'vuex';
Vue.use(Vuex);
const app = new Vue({
el: '#app',
store,
components: {
Counter
},
template: `
<div class="app">
<counter></counter>
</div>
`
})
With this injection mechanism, the sub-component Counter can be accessed through this.$store:
// Counter Component
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
mapState function
computed: {
count () {
return this.$store.state.count
}
}
Does it seem too repetitive to get a state.count attribute with the same name by counting the attribute? We can use the mapState function to simplify this process.
import { mapState } from 'vuex';
export default {
computed: mapState ({
count: state => state.count,
countAlias: 'count', // Alias`count`Equivalent to state => state.count
})
}
There are simpler ways to use it:
computed: mapState([
// Map this.count to store.state.count
'count'
])
Getters object
If we need to do processing calculations on the state object, here are the following:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
If multiple components need to do this, the function will be copied across multiple components.This is very inefficient, and when this process changes and the same changes are made in multiple components, it is more difficult to maintain.
The getters object in Vuex makes it easy for us to do centralized processing in store s.Getters accepts state as the first parameter:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
Called in the Vue through the store.getters object.
computed: {
doneTodos () {
return this.$store.getters.doneTodos
}
}
Getter can also accept other getters as the second parameter:
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
mapGetters auxiliary function
Similar to mapState, you can simplify your code.The mapGetters auxiliary function simply maps getters in the store to locally computed properties:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// Mixing getters into computed objects using object expansion operators
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
It can also be written:
computed: mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
So there are two auxiliary functions in Vue's computed attribute:
import { mapState, mapGetters } form 'vuex';
export default {
// ...
computed: {
mapState({ ... }),
mapGetter({ ... })
}
}
Mutations
As mentioned earlier, mutations are the only way to change the state in a Vuex store.
Each mutation has an event type and a callback handler.
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// Change status
state.count++
}
}
})
Calling mutation requires calling mutation through the store.commit method type:
store.commit('increment')
Payload Submission Load
You can also pass in the second parameter, payload for mutation, to store.commit:
mutaion: {
increment (state, n) {
state.count += n;
}
}
store.commit('increment', 10);
Just passing in an n may not meet our business needs, at which point we can choose to pass in a payload object:
mutation: {
increment (state, payload) {
state.totalPrice += payload.price + payload.count;
}
}
store.commit({
type: 'increment',
price: 10,
count: 8
})
mapMutations function
With no exception, mutations also have a mapping function, mapMutations, to help us simplify our code and use the mapMutations auxiliary function to map methods in components to store.commit calls.
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment' // mapping this.increment() by this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // mapping this.add() by this.$store.commit('increment')
})
}
}
Note Mutations must be a synchronization function.
If we need asynchronous operations, Mutations can't meet our needs, and then we need Actions.
Aciton
Believe that after reading the previous Vuex, you're ready to get started.So let Action learn on its own (it's a bit complicated, and I need time to digest it).
epilogue
Last month I saw Vuex as a fog, and now it seems that Vuex is easy to understand.
The most important thing to learn a new technology is to practice. It is not enough to look at the tutorial and demo alone.
The front end has a long way to go.
Reprint: http://www.jianshu.com/p/caff7b8ab2cfIndividuals have built front-end learning groups designed to learn the front-end together.Pure, pure technical discussion, not disturbed by front-end personnel!Join the group and add me WeChat: iamaixiaoxiao.