乐趣区

关于javascript:Vuex三-纯手写一个超简单的Vuex

目录

  • 剖析 Vuex 的性能
  • 下载模板
  • 剖析模块构造
  • 实现 install 函数
  • 实现 Store 类
  • 替换 vuex

后面学了 Vuex 的概念和应用,还用购物车做了一个残缺的案例,上面看看手写一个简略的Vuex

剖析 Vuex 的性能

  • 首先导入 vuex 的是一个对象
  • 应用 use 挂载到 Vue 的实例上,use办法调用 vuexinstall办法
  • 调用 new Vuex.Store 办法初始化实例
  • 传入参数是一个对象,外面有 stategettersmutationsactions 等属性
  • 应用的时候间接应用 $store.state$store.getters来拜访 store 外面的状态和getter
  • 批改状态能够间接应用 $store.commit 提交mutation
  • 在执行异步操作能够应用 $store.dispatch 散发action

下载模板

  • vuex-myvuex-demo-temp
  • 外面应用了 vuex 进行简略的模仿操作,这里只是简略实现外面的 stategettermutationsactions 属性,其余的办法并不实现。

剖析模块构造

须要一个 vuex 的模块,这个模块须要导出一个 install 办法和一个 Store

let _Vue = null
class Store {}

// install 接管一个参数,Vue 构造函数,前面在 Store 类中还要应用构造函数, 所以在全局定义一个_Vue
function install (Vue) {_Vue = Vue}

export default {
  Store,
  install
}

实现 install 函数

// install 接管一个参数,Vue 构造函数,前面在 Store 类中还要应用构造函数, 所以在全局定义一个_Vue
function install (Vue) {
  _Vue = Vue
  // 1. 创立 Vue 实例传入的 store 对象注入到 Vue 原型上的 $store,在所有组件中用 this.$store 都能够获取到 Vuex 的仓库,从而共享状态
  // 2. 这里咱们获取不到 Vue 的实例,所以这里通过混入 beforeCreate 来获取 Vue 实例,从而拿到选项中的 store 对象
  _Vue.mixin({beforeCreate () {
      // 这里的 this 就是 Vue 的实例
      // 首先判断以后 Vue 的实例的 options 中是否有 store,当创立根实例的时候,会把 store 注入到 Vue 的实例上,如果是组件实例,并没有 store 选项就不须要做这件事件
      if (this.$options.store) {
        // 给 Vue 的原型上挂载 $store
        _Vue.prototype.$store = this.$options.store
      }
    }
  })
}

实现 Store 类

class Store {
  // 构造函数接管一个参数是对象
  constructor (options) {
    // 这里对对象进行解构,并且赋默认值为空对象,防止没有传以后属性
    const {state = {},
      getters = {},
      mutations = {},
      actions = {}} = options
    // 将 state 属性进行响应式解决
    this.state = _Vue.observable(state)
    // 对 getters 属性进行解决
    // getters 是一个对象,对象中有一些办法,这些办法都须要接管 state 参数,并且最终都有返回值,这些办法都是获取值,所以能够应用 Object.defineProperty 将这些办法转换成 get 拜访器
    // 1. 先定义一个 this.getters 让内部能够间接拜访,而后初始化成一个没有原型对象的空对象
    this.getters = Object.create(null)
    // 2. 遍历所有的 getters 的 key,把对应的 key 注册到 this.getters 对象中,定义一个 get 属性,返回 key 对应的 getters 中办法的执行后果,并传入 state
    Object.keys(getters).forEach(key => {
      Object.defineProperty(this.getters, key, {get: () => getters[key](state)
      })
    })
    // 外部属性是公有属性,标识下划线_,不心愿内部拜访
    // 对 mutations 属性进行解决
    this._mutations = mutations
    // 对 actions 属性进行解决
    this._actions = actions
  }

  // 在 commit 办法中获取_mutations
  // 接管两个参数,第一个参数是 type,办法名称,第二个参数是 payLoad,调用办法的参数
  commit (type, payload) {
    // 通过 type 找到 this._mutations 中的办法并调用,传入参数 payload
    this._mutations[type](this.state, payload)
  }

  // 在 dispatch 办法中获取_actions
  // 实现形式和 commit 一样
  dispatch (type, payload) {
    // 第一个参数是 context,这里简略模仿就传入 this,这个外面就有咱们须要的 state,commit 等
    // 第二个参数是 payload
    this._actions[type](this, payload)
  }
}

替换 vuex

index.js 中的 vuex 的导入替换成 ../myVuex,关上浏览器,能够看到mutationactions能够失常执行

import Vuex from '../myVuex'
退出移动版