模拟实现Vuex

96 阅读1分钟
let _Vue = null
class Store { 
  constructor(options) {
    const {
      state = {},
      getters = {},
      mutations = {},
      actions = {}
    } = options
    this.state = _Vue.observable(state)
    
    this.getters = Object.create(null)
    Object.keys(getters).forEach(key => { 
      Object.defineProperty(this.getters, key, {
        get: () => getters[key](state)
      })
    })

    this._mutations = mutations // 私有属性
    this._actions = actions // 私有属性
  }
  /**
   * 提交突变
   * @param {string} type 类型
   * @param {*} payload  参数
   * @return {void}
   */
  commit(type, payload) { 
    this._mutations[type](this.state, payload)
  }
  /**
   * 分发Action
   * @param {*} type
   * @param {*} payload
   * @return {*}
   */
  dispatch(type, payload) {
    this._actions[type](this, payload)
  }
/**
 * @param {*} Vue 构造函数
 * @return {*}
 */
function install(Vue) { 
  _Vue = Vue
  // 此时Vue实例还没有创建,所以无法获取到this实例
  // 通过_Vue.mixin混入beforeCreate,在Vue实例创建的时候,会执行beforeCreate方法,想Vue的原型上添加$store
  _Vue.mixin({
    beforeCreate () {
      if (this.$options.store) { // 只有在Vue的根实例 才有store
        _Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default {
  Store,
  install
}