Vuex basic use

Juejin. Cn/post / 690600…

Juejin. Cn/post / 684490…

// store/index.js
import Vue from 'vue'
import Vuex from '.. /vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  plugins: [].state: {
    time: 1.userInfo: {
      avatar: ' '.account_name: ' '.name: ' '}},getters: {
    getTime (state) {
      console.log('1212',state)
      return state.time
    }
  },
  mutations: {
    updateTime(state, payload){
      state.time = payload
    }
  },
  actions: {
    operateGrou({ commit }) {
      // commit('updateTime', 100)
      return Promise.resolve().then(() = >{
        return {
          rows: [1.2.3]}})}})Copy the code
// main.js
import Vue from "vue";
import App from "./App.vue";
import store from "./store";

new Vue({
  // To access this.$Store property in the Vue component, you need to provide the created store for the Vue instance.
  Vuex provides a mechanism to "inject" the store from the root component to all child components in the form of store options
  store,    
  render: h= > h(App)
}).$mount("#app");
Copy the code

Vuex implementation principle

Tech.meituan.com/2017/04/27/…

www.bilibili.com/video/BV186…


// Basic idea of vuex

let myVue
class Store{
    // All attributes are passed to the new Store instance
    constructor(options){
        // 1. State implementation
        // Core point: Here state is set to reactive by vUE. This is one reason why Vuex can only be used for VUE
        this.vm = new myVue({
            data: {
                return {
                    state: options.state
                }
            }
        })
        // Write the getthis. state as a class accessor to the function for easy extension
        // this.state = this.vm.state
        
        // 2. Getters implementation
        let getters = options.getters
        this.getters = {}
        // Because getters is passed in as an Object, the attributes in the Object are all functions, but are used as attributes, so object.defineProperty is needed (just like calculating attributes).
        Object.keys(getters).forEach(getterName= > {
            Object.defineProperty(this.getters, getterName, {
                get: () = > {
                    // getters[getterName] gets the function
                    return getters[getterName](this.state)
                }
            })
        })
        
        2. mutations implementation (combine commit method) (publish and subscribe model)
        let mutations = options.mutations
        this.mutations = {}
        Object.keys(mutations).forEach(mutationName= > {
            this.mutations[mutationName] = (payLoad) = > {
                mutations[mutationName](state, payLoad)
            }
        })
        
        // 4. Actions implementation (publish subscribe mode)
        let actions = options.actions
        this.actions = {}
        Object.keys(actions).forEach(actionName= > {
            this.actions[actionName] = (payLoad) = > {
                actions[actionName](this, payLoad)
            }
        })
        
        
        
        
    }
    // Class attribute accessors
    get state() {return this.vm.state
    }
    
    // Find the function corresponding to mutationName when publishing
    commit = (mutationName, payLoad) = > {
        this.mutations[mutationName](payLoad)
    },
    
    // Find the corresponding actionName function to execute when publishing
    dispatch = (actionName, payLoad) = > {
        this.actions[actionName](payLoad)
    }

}


// The vuex plug-in is used in the following way: vue.use (vuex)
const install  = (_Vue) = > {
    // The plugin passes in the Vue constructor by default and receives it using the temporary variable myVue, so there is no need to import the Vue library from the vuEX library
    myVue = _Vue
    
    // Core point: with 'mixin'
    // Put the store of vue directly on the prototype, which is wrong, because this would cause all vue instances to have store attributes;
    // All root instance children have $store only from the current root instance

    myVue.mixin({
        // The component is created after the parent
        beforeCreate(){
            // Place the parent component's store property on each component instance
            if(this.$options.store){ / / root instance
                this.$store = this.$options.store
            } else {
                this.$store = this.$parent && this.$parent.$store
            }
        }
    })
}

export {
    Store,
    install
}
Copy the code

Actions Asynchronous operation implementation

Use promise.all to process all asynchronous functions in turn and return the results together

// Dispatch implements asynchronous actions (core idea: publish subscribe)The dispatch method is used at (_type, _payload) {// check object-style dispatch
  const {
      type,
      payload
  } = unifyObjectStyle(_type, _payload) // Configure parameter processing

  // Entry is a collection of all action handlers under the current type
  const entry = this._actions[type]
  if(! entry) {console.error(`[vuex] unknown action type: ${type}`)
    return
  }
  // When the number of functions in entry is greater than 1, promise. all is used to process all function callbacks in turn and return the result
  return entry.length > 1
      ? Promise.all(entry.map(handler= > handler(payload)))
      : entry[0](payload)
}
Copy the code
// commit the simultaneous operation of mutations, which is mainly implemented (release and subscribe of the core idea)
commit (_type, _payload, _options) {
  // check object-style commit
  const {
      type,
      payload,
      options
  } = unifyObjectStyle(_type, _payload, _options)

  const mutation = { type, payload }
  const entry = this._mutations[type]
  if(! entry) {console.error(`[vuex] unknown mutation type: ${type}`)
    return
  }
  // Change the state method exclusively. Other methods are illegal
  this._withCommit(() = > {
    entry.forEach(function commitIterator (handler) {
      handler(payload)
    })
  })
  
  // The subscriber function traverses the execution, passing in the current mutation object and the current state
  this._subscribers.forEach(sub= > sub(mutation, this.state))

  if (options && options.silent) {
    console.warn(
        `[vuex] mutation type: ${type}. Silent option has been removed. ` +
        'Use the filter functionality in the vue-devtools')}}Copy the code