手写基础vuex

发布时间 2023-11-17 16:02:21作者: 柯基与佩奇

实现一个插件:声明 Store 类,挂载$store

Store 具体实现:

  1. 创建响应式的 state,保存 mutations、actions 和 getters
  2. 实现 commit 根据用户传入 type 执行对应 mutation
  3. 实现 dispatch 根据用户传入 type 执行对应 action,同时传递上下文
  4. 实现 getters,按照 getters 定义对 state 做派生
// 目标1:实现Store类,管理state(响应式的),commit方法和dispatch方法
// 目标2:封装一个插件,使用更容易使用
let Vue;

class Store {
  constructor(options) {
    // 定义响应式的state
    // this.$store.state.xx
    // 借鸡生蛋
    this._vm = new Vue({
      data: {
        $$state: options.state,
      },
    });

    this._mutations = options.mutations;
    this._actions = options.actions;

    // 绑定this指向
    this.commit = this.commit.bind(this);
    this.dispatch = this.dispatch.bind(this);
  }

  // 只读
  get state() {
    return this._vm._data.$$state;
  }

  set state(val) {
    console.error("不能直接赋值呀,请换别的方式!!天王盖地虎!!");
  }

  // 实现commit方法,可以修改state
  commit(type, payload) {
    // 拿出mutations中的处理函数执行它
    const entry = this._mutations[type];
    if (!entry) {
      console.error("未知mutaion类型");
      return;
    }

    entry(this.state, payload);
  }

  dispatch(type, payload) {
    const entry = this._actions[type];

    if (!entry) {
      console.error("未知action类型");
      return;
    }

    // 上下文可以传递当前store实例进去即可
    entry(this, payload);
  }
}

function install(_Vue) {
  Vue = _Vue;

  // 混入store实例
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store;
      }
    },
  });
}

// { Store, install }相当于Vuex
// 它必须实现install方法
export default { Store, install };