手写简版vuex

182 阅读1分钟

手写简版vuex,完成包括state,mutations,actions,getters操作

let Vue
class Store {
  constructor(options) {
    this.$options = options
    this._mutations = options.mutations
    this._actions = options.actions
    // 采用 new Vue({}) 的方式来建立响应式数据
    this._vm = new Vue({
      data () {
        return {
          $$state: options.state
        }
      }
    })

    this.getters = {}
    Object.keys(options.getters).forEach(key => {
      Object.defineProperty(this.getters, key, {
        get: () => {
          return options.getters[key](this.state)
        },
        enumerable: true
      })
    })

    this.commit = this.commit.bind(this)
    this.dispatch = this.dispatch.bind(this)
  }

  // 防止state被直接调用set,所以自设getter,setter
  get state () {
    return this._vm._data.$$state
  }

  set state (newValue) {
    console.log('no no no', newValue)
  }

  commit (type, payload) {
    const mutation = this._mutations[type]
    mutation && mutation(this.state, payload)
  }

  dispatch (type, payload) {
    const action = this._actions[type]
    action && action(this, payload)
  }
}

function install (_Vue) {
  Vue = _Vue
  Vue.mixin({
    beforeCreate () {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
export default { Store, install }