Vuex registration:
// Import store in main.js and register with Vue
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h= > h(App)
}).$mount('#app')
Copy the code
Vuex configuration:
// store index.js file to configure vuex:
import Vue from 'vue'
import Vuex from 'vuex'// Import the Vuex object
Vue.use(Vuex)// Call vuex's install method
// Store is a constructor that takes five attributes as arguments
export default new Vuex.Store({
// The state management repository stores the states that need to be managed uniformly in the state
state: {},
// Vuex allows us to define "getters" in stores (think of as computed properties of stores). Just like evaluating properties, the return value of a getter is cached based on its dependency and is recalculated only if its dependency value changes
getters: {},
// The only way to change the state in Vuex's store is to commit mutation. Mutations in Vuex are very similar to events: each mutation has a string event type (type) and a callback function (handler). This callback is where we actually make the state change, and it accepts state as the first argument
mutations: {},
// the Action commits mutation instead of a direct state change; Actions can contain any asynchronous operation
actions: {},
// Vuex allows us to split the store into modules. Each module has its own state, mutation, action, getter, and even nested submodules
modules: {},})Copy the code
In a nutshell: There are five attributes in VUEX for state management,
- State Indicates the unified storage status to be managed.
- Getters is equivalent to computed in VUE, which listens for state changes to perform response operations;
- Mutations change the status of the simultaneous operation;
- Actions An asynchronous operation to change the status, and eventually submit mutations;
- Modules can be simply understood as module state management, which has all the functions of VUEX.
Basic use of Vuex:
MapState, mapGetters, mapMutations helper function: simplify the use of $store. State…
- state
// store file index.js
export default new Vuex.Store({
state: {
count: 0.msg: "hello VueX"}})// ---------- state uses -----------
// 1. $store.state.count
// 2. Simplify usage: use count directly
import { mapState } from "vuex"
export default {
// Strict :true,// Strict mode is enabled, but exceptions are thrown. In the production environment, strict mode is not recommended to be enabled, because the status tree in-depth check affects performance
strict: process.env.NODE_ENV ! = ="production".computed: {
// mapState returns an object containing two methods for calculating attributes as follows:
// {count: state => state.count,.. }
// The argument to mapState can accept arrays or objects
/ /... mapState(['count','msg'])
// If count MSG already exists in data, set the attribute name. mapState({num: 'count'.message: 'msg'}}})Copy the code
- getters
// store file index.js
export default new Vuex.Store({
state: {
count: 0.msg: "hello VueX"
},
// A getter is a component's calculated property that processes and displays state data
getters: {
reverseMsg(state) {
return state.msg.split(' ').reverse().join(' ')}}})// ---------- getters uses -----------
// 1. $store.getters.reverseMsg
// 2. Simple use: Use reverseMsg directly
import { mapGetters } from "vuex";
export default {
computed: {
// mapGetters returns an object containing two methods for calculating attributes as follows:
// count: state => state.count
/ /... mapGetters(['reverseMsg','...'])
// If there is a reverseMsg property name in data. mapGetters({msg: 'reverseMsg'.'... ': '... '}}})Copy the code
- mutations
// store file index.js
// Change the state mutation in the view
export default new Vuex.Store({
// Click the button to increase the value
mutation: {
/ / state
// Payload Additional parameters, which can be objects
increate(state, payload) {
state.count += payload
}
}
})
/ / -- -- -- -- -- -- -- -- -- -- mutation use -- -- -- -- -- -- -- -- -- -- - devtools convenient debugging
The essence of // mutation is a method, which requires the commit method to be used. The map function is used to map the mutation into the mes of the current component
// Each time you click the button, count is incremented by one
// 1. @click = "$store.commit('increate',1)"
@click = "inc(1)"
MapMutations returns an object corresponding to the mutation method. Instead of calculating the attributes, it needs to be added to methods
import { mapMutations } from "vuex";
export default {
methods: {
...mapMutations({ inc: 'increate'.'... ': '... '}}})Copy the code
- actions
// store file index.js
// Execute the asynchronous state actions
export default new Vuex.Store({
actions: {
// The first argument to context contains the state Commit getters member
increateAsync(context, payload) {
setTimeout(() = > {
// submit to mutations
context.commit('increate', payload)
}, 2000)}}})// ---------- action uses -----------
// 1. @click = "$store.dispatch.('increateAsync',1)"
@click = "inc(1)"
// mapActions returns an object corresponding to a method in Actions, which is no longer a calculated property and needs to be placed in methods
import { mapActions } from "vuex";
export default {
methods: {
...mapActions({ inc: 'increateAsync'.'... ': '... '}}})Copy the code
- modles
// Import the vuEX module. The content of the module is the same as the main module
import cart from "./module/cart";
import products from "./module/products";
export default new Vuex.Store({
modules: {
cart,
products
}
})
// ---------- modules use -----------
// 1. @click = "$store.commit('setNums',[])
// 2. Cart is stored in $store.state and is called with $store.state. Call; Mutation call as above
// 3. Namespace: for example, the mutation method in modules has the same name as the mutation method in state
import { mapState } from "vuex"
export default {
computed: {
...mapState(['setCart']),// State setCart managed in the main module. mapState("cart"["setCart"]) // State managed in cart setCart
},
methods: {
...mapMutations("cart", { setc: 'setCart'.'... ': '... '})}Copy the code
Simulation simple VUEX
Use in components: We will only implement the following four property capabilities
<template> <div id="app"> <h1> vuex-demo </h1> <h2>State</h2> count: {{$store.state.count}} <br> MSG: {{$store.state. MSG}} <h2>Getter</h2> {{$store.getters. ReverseMsg}} <h2>Mutation</h2> call $store.mit <button @click="$store.commit('increate', 2)">Mutation</button> <h2>Action</h2 @click="$store.dispatch('increateAsync', 5)">Action</button> </div> </template>Copy the code
From the configuration we know that Vuex returns an object:
- Call Vuex’s install method with vue.use (),
- Vuex contains the Store constructor, which takes five attributes as arguments
import Vuex from 'vuex' // Import the Vuex object
Vue.use(Vuex) // Call vuex's install method
export default new Vuex.Store({}) // Store is a constructor that takes five attributes as arguments
Copy the code
Vuex basic structure:
// We can get the vue constructor in install, and we will use the vue constructor in store later, so we define _Vue in advance
let _Vue = null
// Define the Store class
class Store {}
// All plug-ins have an install method. Vuex's install method mounts Store to vuue.$Store
// Install needs to accept two arguments, one Vue and an additional option, since we are emulating simple Vuex, only Vue arguments are accepted
function install (Vue) {
_Vue = Vue
}
// Export the content
export default {
Store,
install
}
Copy the code
Install implementation:
function install (Vue) {
_Vue = Vue
_Vue.mixin({ // Inject Store into the vue instance to make Store accessible through $Store in all components
beforeCreate () {
// This is a vue instance. If it is a component instance, there is no store object
if (this.$options.store) {
_Vue.prototype.$store = this.$options.store
}
}
})
}
Copy the code
The Store class implements:
class Store {
// Store accepts five attribute parameters
constructor(options){
const {
state = {}, // Set the default value {} to prevent errors if the user does not pass this attribute
getters = {},
mutations = {},
actions = {}
} = options // Attribute structure in the parameter
// state
this.state = _Vue.observable(state) // Set the state property to reactive data
// getters
this.getters = Object.create(null)
Object.keys(getters).forEach(key= > {
// Create a getters object, iterate over the object properties, and register the key in this. Getters with definedProperty
Object.defineProperty(this.getters, keys, {
get: () = > getters[key](state)
})
})
// Store mutations and Actions into the corresponding properties, which will be obtained in commit and dispatch
this._mutations = mutations
this._actions = actions
}
/ / the commit method
commit( type, payload){
this._mutations[type](this.state, payload)
}
diapatch( type, payload){
this._actions[type](this, payload)
}
}
Copy the code
Conclusion:
- State: Uses the Vue Observable to set the state in state to reactive data
- Getters: Mount the method defined in getters to the store using Object.defineProperty(), pass in state, and execute the response method
- Mutations, action: invokes internal methods through commit and dispatch methods