Vuex的简单实现

根据本身所学知识,实现一个low版本Vuexhtml

第一步 分析

  1. 做为一个Vue插件,须要实现install方法,详情参考这里
  2. 在日常使用的过程是,是Vuex.Store,因此要实现这个方法,同时还须要接收传入的配置 options
  3. 有四个数据,分别是state,mutations,actions,getters,还有一个commitdispatch方法
  4. 明确各项任务
    1. state 数据
    2. mutations 负责改变数据
    3. getters获得数据
    4. actions,执行异步,提交mutations

第二步 框架搭建

Store方法

options.getters && this.handleGetters(options.getters)vue

这个方法是在调用的时候发现有getters,就执行这个函数返回结果vuex

let Vue

class Store {
  constructor (options = {}) {
    this.state = new Vue({ data: options.state })
    this.$options = options
    this.mutations = options.mutations || {}
    this.actions = options.actions
    options.getters && this.handleGetters(options.getters)
  }

  commit = (type, arg) => { 
      
  }

  dispatch (type, arg) {
    
  }

	// 控制getters方法
  handleGetters (getters) {
    
  }
}

// install方法
function install (_vue) {
  Vue = _vue // 会返回一个vue实例
  Vue.mixin({
    beforeCreate () {
      if (this.$options.store) { // 负责挂载
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

export default {
  Store,
  install
}
	
复制代码

install方法

function install (_vue) {
  Vue = _vue // 会返回一个vue实例
  Vue.mixin({
    beforeCreate () {
      if (this.$options.store) { // 负责挂载
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}
复制代码

第三步 具体实现

commit方法

commit = (type, arg) => { // 默认指向定义它时,所处上下文的对象的this指向
    this.mutations[type](this.state, arg)
  }
复制代码

这个这叫好理解,从mutations里获取道咱们因此要的方法,而后传递参数,值得注意的是this,指向框架

dispatch

dispatch (type, arg) {
    this.actions[type]({ // this表明着它的直接调用者
      commit: this.commit,
      state: this.state
    }, arg)
  }
复制代码

这个也比较简单,不作叙述了异步

handleGetters

handleGetters (getters) {
    this.getters = {}
    // Object.keys 返回 getters对象的key
    Object.keys(getters).forEach(key => {
      // 参考网址 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
      Object.defineProperty(this.getters, key, {
        get: () => {
          return getters[key](this.state)
        }
      })
    })
  }
复制代码

Object.keys参考

参考网址ide

定义一个对象,循环拿到对应的函数名称,而后向这个对象上定义 函数名称的属性,增长get方法。 传进来的getters是一个对象模块化

第四步 完整代码

let Vue

class Store {
  constructor (options = {}) {
    this.state = new Vue({ data: options.state })
    this.$options = options
    this.mutations = options.mutations || {}
    this.actions = options.actions
    options.getters && this.handleGetters(options.getters)
  }

  commit = (type, arg) => { // 默认指向定义它时,所处上下文的对象的this指向
    this.mutations[type](this.state, arg)
  }

  dispatch (type, arg) {
    this.actions[type]({ // this表明着它的直接调用者
      commit: this.commit,
      state: this.state
    }, arg)
  }

  handleGetters (getters) {
    console.log(getters)
    this.getters = {}
    // Object.keys 返回 getters对象的key
    // 参考网址 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
    Object.keys(getters).forEach(key => {
      // 参考网址 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
      Object.defineProperty(this.getters, key, {
        get: () => {
          return getters[key](this.state)
        }
      })
    })
  }
}

function install (_vue) {
  Vue = _vue // 会返回一个vue实例
  Vue.mixin({
    beforeCreate () {
      if (this.$options.store) { // 负责挂载
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

export default {
  Store,
  install
}

复制代码

store里面的代码

import Vue from 'vue'
import Vuex from './../myvuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: { // 状态
    count: 0
  },
  mutations: { // 改变状态
    increment (state, n = 1) {
      state.count += n
    }
  },
  getters: {
    score (state) {
      return `一个共${state.count}`
    }
  },
  actions: { // 复杂的逻辑 作异步操做 参考网址 https://vuex.vuejs.org/zh/guide/actions.html
    incrementAsync ({ commit }) {
      setTimeout(() => {
        commit('increment', 2) // 提交一个mutations
      }, 1000)
    }
  },
  modules: { // 模块化
    // 具体参考https://vuex.vuejs.org/zh/guide/modules.html
  }
})

复制代码
相关文章
相关标签/搜索