手写简易Vuex

首先确定需求,vuex的功能是实现状态集中管理,其中需要实现的内容

  • store
  • state
  • mutations
  • actions
  • getters
  • 响应式

代码实现

let Vue;

class Store {
  constructor(options) {
    // 同样对vue强依赖 使用vue实现响应数据的更新
    this.state = new Vue({
      data: options.state
    });

    this.mutations = options.mutations;
    this.actions = options.actions;

    options.getters && this.handleGetters(options.getters);
  }

  //为什么没有定义到构造器内部?因为每个实例可以公用这些方法
  // 为mutations actions getters为每个实例化单独享有的
  
  // 声明为箭头函数,why?为了直接可以使用this.mutations,this.state
  commit = (type, arg) => {
    this.mutations[type](this.state, arg);
  };

  dispatch(type, arg) {
    this.actions[type](
      {
        commit: this.commit,
        state: this.state
      },
      arg
    );
  }
// getters为参数 而this.getters是实例化的
  handleGetters(getters) {
    this.getters = {};
    // 遍历getters所有key
    Object.keys(getters).forEach(key => {
      // 为this.getters定义若干属性,这些属性是只读的
      // $store.getters.score
      Object.defineProperty(this.getters, key, {
        get: () => {
          return getters[key](this.state);
        }
      });
    });
  }
}

function install(_Vue) {
  Vue = _Vue;

  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store;
      }
    }
  });
}

export default { Store, install };

要点分析

vue使用外来依赖

因为插件本身就使用了传入的vue,因此尽量不要内部定义vue,直接从从参数获取。

mixin

是否需要混入,混入本身很好用,但使用混入的最大前提是需要拿到组件的实例,如果你不希望或者不用拿到,那么直接定义到Vue的原型上即可。

getter为什么是只读的

通过Object.defineProperty实现定义一个get函数,让其变成只读的

箭头函数

当你需要使用外部环境,并且在组件实例的使用中不受影响的话,你就因该考虑箭头函数。

 

 

原文地址:https://www.cnblogs.com/LeoXnote/p/14107060.html