1 Introduction
Vuex is a state management mode specially developed for Vue.js applications. It uses centralized storage to manage the state of all components of the application, and ensures that the state changes in a predictable way with corresponding rules.
Application scenario: communication between components at the same level, such as the following:
let comA = {} let comB = {}
2 basic use
2.1 state
State (similar to data in vue instances) the state component stores shared data and extracts public variables from each vue instance for unified management.
state: { msg: 'hello vuex' } //In vue, the state stored in vuex is obtained by calculating attributes, which can be obtained directly or through auxiliary functions computed: { count() { return this.$store.state.count } // perhaps ...Vuex.mapState(["count"]) }
2.2 getters
Getters (similar to computed in the vue instance) is a method used to calculate and return the static data in the state after obtaining the state and processing the state data.
getter: { //Parameter is the default parameter -- derived from state reMsg(state) { Returns the result after the operation return state.msg.toUpperCase() } } stay vue Can be accessed by calculating properties computed: { reMsg() { return this.$store.getters.reMsg } // perhaps ...Vuex.mapGetters(["reMsg"]) }
2.3 mutations
Changes is the only way to modify state data. It is generally used for some synchronization operations. The only way to change the state in Vuex's store is to submit changes, which must be synchronous operations. The first parameter of the mutation function is state, and the second parameter is to accept the arguments passed by the user when calling mutation.
mutations: { SET_MSG(state, payload) { state.msg = payload } } Can be in vue Submit mutation in life cycle hook or methods Mapping mutation method in created() { // The first parameter is the name of the mutation method, and the second parameter is the passed argument this.$store.commit('SET_MSG', 'hello mutation') } methods:{ ...Vuex.mapMutations(['SET_MSG']) }
2.4 actions
actions is used to store asynchronous request methods. actions submit mutation, which indirectly changes the state in state. Asynchronous requests in action s accept a formal parameter - context (context object)
(1)context.state get state
(2)context.getters get Getters
(3)context.commit() commit
(4)context.dispatch() distribution action
actions: { async findAll(context) { let res = await axios.get('http://...'); // Submit mutation context.commit('SET_MSG', res.data.data) } } Can be in vue Distribute actions in the lifecycle hook or methods Medium mapping actions Methods in created() { // Parameter 1 is the name of the asynchronous function, and parameter 2 can pass arguments this.$store.dispatch('findAll') } methods:{ ...Vuex.mapActions(['findAll']) }
2.5 case - define state machine instance
<title>vue</title> <script src="../js/vue.js"></script> <script src="../js/vuex.js"></script> </head> <body> <div id="app"> <h3>{{data1}}</h3> <h4> vuex-state-{{msg}} <button @click="$store.commit('SET_MSG','bye vuex')">Modify state machine button</button> </h4> <h5>vuex-getters-{{upperMsg}}</h5> <ul> <li v-for="(item,index) in categories" :key="index"> Column No.:{{item.id}} Column name:{{item.name}} </li> </ul> </div> <script> // 1. Declare Vuex instances let store = new Vuex.Store({ state:{ msg:'this is vuex data', categories:[] }, getters:{ upperMsg(state){ return state.msg.toUpperCase() } }, // Change of internal state of state machine mutations:{ // Mutation is the only way to modify the data in state // The mutation method accepts two formal parameters, the first is state, and the second is the argument passed when calling the mutation SET_MSG(state,payload){ state.msg = payload; }, SET_CATEGORIES(state,payload){ state.categories = payload; } }, actions:{ // Action, which is used to store asynchronous methods shared by components // context object async findAllCategories(context){ // es6 // let res = await ajax () let res = { status:200, message:'query was successful', data:[ {id:1,name:'Campus news'}, {id:2,name:'Campus information'}, {id:3,name:'Entertainment News'}, {id:4,name:'Campus news'}, ], timestamp:1634817659543 } // Submit mutation to modify the data inside the state machine console.log(context); // Submit the mutation through the commit() method. The first parameter is the name of the mutation function, and the second is the argument of the mutation function context.commit('SET_CATEGORIES',res.data) } } }) let vm = new Vue({ el:"#app", data:{ data1:'this is vm data' }, computed:{ // Map the data in vuex state by calculating attributes msg(){ return this.$store.state.msg }, categories(){ return this.$store.state.categories; }, // By calculating attributes, vuex upperMsg(){ return this.$store.getters.upperMsg }, }, methods:{}, created(){ // In this hook function, the action in the vuex state machine is called. // Distribute actions through dispatch() this.$store.dispatch('findAllCategories'); // Submit mutation // this.$.store.commit('SET_MSG ',' Hello, state machine ') }, // 2. Inject the state machine instance into the vue instance store:store }) </script>
3 auxiliary function
The Vuex constructor provides a quick method for mapping data and methods. It uses the object deconstruction to deconstruct the internal auxiliary functions.
let { mapState, mapGetters, mapMutations, mapActions } = Vuex use computed: { ...mapState(['msg']), // State mapping ...mapGetters(['reMsg']) // Calculate attribute mapping }, methods: { ...mapMutations(['SET_MSG']), // Mutation mapping ...mapActions(['findAll']) // Action mapping }
4. Modular development
4.1 purpose of modularization
Due to the use of a single state tree, all the states of the application will be concentrated in a relatively large object. When the application becomes very complex, the store object may become quite bloated. To solve the above problems, Vuex allows us to divide the store into modules. Each module has its own state, mutation, action, getter, and even nested sub modules. Named means to set the namespace
4.2 modular use
<title>Modular development</title> <script src="../js/vue.js"></script> <script src="../js/vuex.js"></script> </head> <body> <div id="app"> <div>moduleA: state-{{msg1}} getters-{{upperMsg1}} <button @click="SET_MSG1('Hello, modularity A')">modify A data</button> </div> <div>moduleB: state-{{msg2}} getters-{{upperMsg2}} <button @click="SET_MSG2('Hello, modularity B')">modify B data</button> </div> </div> <script> // 1. Define state machine sub module let moduleA = { namespaced: true, state() { return { msg1: 'this is moduleA data' } }, getters: { upperMsg1(state) { return state.msg1.toUpperCase() } }, mutations: { SET_MSG1(state, payload) { state.msg1 = payload } }, actions: {} } let moduleB = { namespaced: true, state() { return { msg2: 'this is moduleB data' } }, getters: { upperMsg2(state) { return state.msg2.toUpperCase() } }, mutations: { SET_MSG2(state, payload) { state.msg2 = payload } }, actions: {} } let store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) let { mapState, mapGetters, mapMutations, mapActions } = Vuex let vm = new Vue({ el: '#app', data: {}, computed: { // In the calculation attribute, map the state/getters in vuex through auxiliary functions ...mapState('a', ['msg1']), ...mapState('b', ['msg2']), ...mapGetters('a', ['upperMsg1']), ...mapGetters('b', ['upperMsg2']), }, methods: { // In the methods of the instance, map changes through auxiliary functions ...mapMutations('a', ['SET_MSG1']), ...mapMutations('b', ['SET_MSG2']), }, created() { }, store }) </script>