What is Vuex?
Vuex is a state management mode developed specifically for vuue.js applications. Vuex is a global state management mode
What is Vuex used for?
Vuex is used to transfer values between components, and multiple components share data. The data of Vuex is responsive. When we update A state in component A, component B will update dynamically
State
State is used to store State
In the componentVuex
state
Since Vuex’s state store is reactive, the easiest way to read state from a Store instance is to return some state in a calculated property:
computed: {
count: () = > store.state.count
// Or "injects" state from the root component into each child component vue.use (Vuex)
count: () = > this.$store.state.count
},
Copy the code
MapState Indicates the obtaining mode
import { mapState } form 'vuex'
computed: {
...mapState({
// 1. Basic usage store/index.js
isLogin: (state) = > state.isLogin
// 2. Use the module store/modules/user.js
isLogin: (state) = > state.user.isLogin
}),
},
Copy the code
Getters
Getters is similar to computed properties and is reevaluated only when its dependencies change
The Getter accepts state as its first argument:
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)
}
}
})
Copy the code
Used in components
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
Copy the code
MapGetters Indicates the method of obtaining the file
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// Mix getters into a computed object using the object expansion operator. mapGetters(['doneTodosCount'.'anotherGetter'.// ...
])
// Use Modules store/user.js. mapGetters('user'['increment'.'incrementBy'.// ...])}}Copy the code
Mutations
The only way to change the state in the Store is mutations
The first parameter on mutations is state
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// Change the state
state.count++
}
}
})
Copy the code
A method is called
store.commit('increment')
Copy the code
You can pass extra parameters to store.mit
// ...
mutations: {
increment (state, n) {
state.count += n
}
}
Copy the code
store.commit('increment'.10)
Copy the code
Remember that Mutation must be a synchronization function
Commit Mutation in the component
computed: {
doneTodosCount () {
return this.$store.commit('increment')}}Copy the code
Submit via mapMutations
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
// Mix getters into a computed object using the object expansion operator. mapMutations(['increment'.'incrementBy'.// ...
])
// Use Modules store/user.js. mapMutations('user'['increment'.'incrementBy'.// ...])}}Copy the code
Action
Action is similar to mutation, except that:
- The Action commits mutation rather than a direct state change.
- Actions can contain any asynchronous operation.
Register 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
The Action function accepts a context object with the same methods and properties as the store instance, so you can submit a mutation by calling context.mit. Or get state and getters via context.state and context.getters.
In practice, we often use ES2015’s parameter deconstruction new Window to simplify code
actions: {
increment ({ commit }) {
commit('increment')}}Copy the code
Trigger an Action in the component
methods: {
increment () {
this.$store.dispatch('increment')}}Copy the code
Triggered in mapActions mode
import { mapActions } from 'vuex'
export default {
// ...
methods: {
// Mix getters into a computed object using the object expansion operator. mapActions(['increment'.'incrementBy'.// ...
])
// Use Modules store/user.js. mapActions('user'['increment'.'incrementBy'.// ...])}}Copy the code
Combination of the Action
Sometimes you need to combine multiple actions, such as calling actionA in actionB
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
commit('someMutation')
resolve()
}, 1000)}}}Copy the code
With async/await, we can combine actions as follows:
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
commit('someMutation')
resolve()
}, 1000)})}async actionB ({ dispatch, commit }) {
await dispatch('actionA') // Wait for actionA to complete
// ...}}Copy the code
Modules
When the application becomes very complex, the Store object can become quite bloated. Modules splits the store into modules. Each module has its own state, mutation, action, getter, and even nested submodules.
const moduleA = {
state: () = >({... }),mutations: {... },actions: {... },getters: {... }}const moduleB = {
state: () = >({... }),mutations: {... },actions: {... }}const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
Copy the code
Project Use Case
@ / store/modules/user. Js:
export default {
namespaced: true.state: {
// Store the state
isLogin: false
},
mutations: {
// Change the status
SET_ISLOGIN(state, val) {
state.isLogin = val
}
},
actions: {
// Asynchronous operation
login({ commit }, query) {
api.login({
code: query.code,
iv: query.iv
}).then(res= > {
commit('SET_ISLOGIN'.true)})}}}Copy the code
@/store/index.js :
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
/ / Vuex installation
Vue.use(Vuex)
// Create a store
export default new Vuex.Store({
modules: {
user,
// ...}})Copy the code
@/main.js :
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from '@/store';
new Vue({
router,
store,
render: h= > h(App)
}).$mount('#app');
Copy the code