Core concepts
Store has five core concepts, State, Getters, Mutations, Actions, and Modules. You have to know what they do.
State status
Each of our projects basically uses the same store instance, so the State is also shared. State is an object and the only data source. The data in the entire Store is managed and stored from the State. State is actually like option data in a Vue instance.
Basic case
Get State data in the component
Since State is reactive, it can be returned in conjunction with computed properties. Whenever state.count
changes, the calculated property will be re-evaluated and an update of the associated DOM will be triggered.
<template> <div class="home"> {<!-- -->{ count }} </div> </template> <script> export default { computed: { count() { return this.$store.state.count } } } </script>
Get State data through mapState auxiliary function
When a component needs to obtain multiple State states, it will be somewhat repetitive and redundant to declare these states as computed properties. To solve this problem, we can use the mapState helper function to help us generate calculated properties to optimize your code.
<template> <div class="home"> {<!-- -->{ count }} </div> </template> <script> import { mapState } from 'vuex' export default { computed: { ...mapState({ count: (state) => state.count, name: (state) => state.name }) } } </script>
Getters computed properties
Sometimes we need to derive some state from the state in the store. In this case, we need to use getters. In fact, getters are the same as computed properties. Because in some cases you feel that the state data is not in the format you want, you want to process it based on it and then use it. Of course, it will not affect the value of the original state.
Basic case
Define Getters and process them based on the original State
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({<!-- --> state: {<!-- --> name: 'xiaoming' }, getters: {<!-- --> name(state) {<!-- --> return 'my name is ' + state.name } } }) export default store
Get Getters data in the component
<template> <div class="home"> {<!-- -->{ name }} </div> </template> <script> export default { computed: { name() { return this.$store.getters.name } } } </script>
Get Getters data through mapGetters helper function
<template> <div class="home"> {<!-- -->{ myName }} </div> </template> <script> import { mapGetters } from 'vuex' export default { computed: { // Map `this.name` to `this.$store.getters.name` ...mapGetters({ myName: 'name' }) } } </script>
Mutations synchronously modify State
The only way to change state in a Vuex store is to submit a mutation. Mutations are very similar to when Vue calls a child component, it passes data to the child component, and the child component notifies the parent component to modify the data through $emit
. All use one-way data flow.
Basic case
Define mutations
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({<!-- --> state: {<!-- --> count: 0 }, mutations: {<!-- --> increment(state, payload) {<!-- --> state.count + = payload.num } } }) export default store
Submit Payload
Mutations are called via $store.commit
, and additional parameters can be passed in, namely the payload of the mutation.
<template> <div class="home"> {<!-- -->{ $store.state.count }} </div> </template> <script> export default { mounted() { setTimeout(() => { this.$store.commit('increment', { num: 10 }) }, 1000) } } </script>
Get mutations function through mapMutations auxiliary function
You can use this.$store.commit('$mutationsName')
in the component to commit mutations, or use the mapMutations helper function to map the methods in the component to $store.commit
call.
<template> <div class="home"> {<!-- -->{ $store.state.count }} </div> </template> <script> import { mapMutations } from 'vuex' export default { methods: { // Map `this.myIncrement()` to `this.$store.commit('increment')` ...mapMutations({ myIncrement: 'increment' }) }, mounted() { setTimeout(() => { this.myIncrement({ num: 10 }) }, 1000) } } </script>
Mutation needs to comply with Vue’s responsiveness rules
Since the state in the Vuex store is reactive, when we change the state, the Vue component that monitors the state will automatically update. This also means that mutations in Vuex also need to follow the same precautions as using Vue: for example, it is best to initialize all required states in your Store in advance.
Mutation must be a synchronous function
An important principle is to remember that mutations must be synchronous functions, and the internal logic must be synchronous. If it is asynchronous, the status cannot be tracked normally.
Actions asynchronously submit Mutations
Mixing asynchronous calls within mutations can make your program difficult to debug. For example, when you call two mutations that contain asynchronous callbacks to change state, how do you know when to call back and which one to call first? This is why we distinguish between these two concepts. In Vuex, mutations are all synchronous transactions and must modify the current state immediately.
Actions are similar to mutations. The difference between them is that Actions submit mutations instead of directly changing the state. Actions are asynchronous, and functions can contain any asynchronous operations.
Basic case
Define actions
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({<!-- --> state: {<!-- --> count: 0 }, mutations: {<!-- --> increment(state, payload) {<!-- --> state.count + = payload.num } }, actions: {<!-- --> incrementAsync({<!-- --> commit }, payload) {<!-- --> setTimeout(() => {<!-- --> commit('increment', payload) }, 1000) } } }) export default store
Distribute actions
Actions are triggered via the $store.dispatch
method.
<template> <div class="home"> {<!-- -->{ $store.state.count }} </div> </template> <script> export default { mounted() { this.$store.dispatch('incrementAsync', { num: 10 }) } } </script>
Get the actions function through the mapActions helper function
<template> <div class="home"> {<!-- -->{ $store.state.count }} </div> </template> <script> import { mapActions } from 'vuex' export default { methods: { // Map `this.myIncrementAsync()` to `this.$store.dispatch('incrementAsync')` ...mapActions({ myIncrementAsync: 'incrementAsync' }) }, mounted() { this.myIncrementAsync({ num: 10 }) } } </script>
Module module
Since the same state is used, all the states of the application will be concentrated into a relatively large object. When an application becomes very complex, store objects have the potential to become quite bloated.
In order to solve the above problems, Vuex allows us to split the store into modules. Each module has its own state, getters, mutations, actions, and modules.
Basic case
Define module
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const moduleA = {<!-- --> namespaced: true, state: {<!-- --> count: 0, name: 'xiaoming' }, getters: {<!-- --> name(state) {<!-- --> return 'my name is ' + state.name } }, mutations: {<!-- --> increment(state, payload) {<!-- --> state.count + = payload.num } }, actions: {<!-- --> incrementAsync({<!-- --> commit }, payload) {<!-- --> setTimeout(() => {<!-- --> commit('increment', payload) }, 1000) } } } const store = new Vuex.Store({<!-- --> modules: {<!-- --> a: moduleA } }) export default store
Get State data through mapState auxiliary function
<template> <div class="home"> {<!-- -->{ name }} </div> </template> <script> import { mapState } from 'vuex' export default { computed: { // Map `this.name` to `this.$store.state.a.name` ...mapState({ name: (state) => state.a.name }) } } </script>
Get Getters data through mapGetters helper function
<template> <div class="home"> {<!-- -->{ myName }} </div> </template> <script> import { mapGetters } from 'vuex' export default { computed: { // Map `this.myName` to `this.$store.getters['a/name']` ...mapGetters({ myName: 'a/name' }) } } </script>
Get mutations function through mapMutations auxiliary function
<template> <div class="home"> {<!-- -->{ $store.state.a.count }} </div> </template> <script> import { mapMutations } from 'vuex' export default { methods: { // Map `this.myIncrement()` to `this.$store.commit('a/increment')` ...mapMutations({ myIncrement: 'a/increment' }) }, mounted() { setTimeout(() => { this.myIncrement({ num: 10 }) }, 1000) } } </script>
Get the actions function through the mapActions helper function
<template> <div class="home"> {<!-- -->{ $store.state.a.count }} </div> </template> <script> import { mapActions } from 'vuex' export default { methods: { // Map `this.myIncrementAsync()` to `this.$store.dispatch('a/incrementAsync')` ...mapActions({ myIncrementAsync: 'a/incrementAsync' }) }, mounted() { this.myIncrementAsync({ num: 10 }) } } </script>
Original link: vegetable garden front end