实现一个vuex

2021-03-31  本文已影响0人  三天两觉_
let Vue
class Store {
  constructor(optoins) {
    this._mutations = optoins.mutations
    this.actions = optoins.actions
    this.commit = this.commit.bind(this)
    this.dispatch = this.dispatch.bind(this)
    this.wrapperGetters = optoins.getters;

    const computed = {}
    this.getters = {}

    const store = this
    Object.keys(this.wrapperGetters).forEach((key) => {
      const fn = this.wrapperGetters[key];
      //vue实例computed没有参数,但是getters中的函数是有参数的,默认传入state,所以做一层包裹处理
      computed[key] = function() {
        return fn(store.state)
      }
      Object.defineProperty(store.getters, key, {
        get() {
          return store._vm[key]
        },
      })
    })
    //借vue实现store中数据的响应式
    this._vm = new Vue({
      data: {
        state: optoins.state,
      },
      computed,
    })
  }
  get state() {
    return this._vm.state
  }
  //设置state不能修改
  set state(val) {
    console.error('no allowed to modify state')
  }
  commit(type, payload) {
    const entry = this._mutations[type]
    if (!entry) {
      return console.error('unknow mutations type:' + type)
    }
    entry(this.state, payload)
  }
  dispatch(type, payload) {
    let entry = this.actions[type]
    if (!entry) {
      return console.error('unknow actions type:' + type)
    }
    //传递一个上下文,其实就是当前的store实例
    entry(this, payload)
  }
}
function install(_vue) {
  Vue = _vue
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    },
  })
}

export default { Store, install }
上一篇 下一篇

猜你喜欢

热点阅读