基于Vuex从零实现自己的Vuez插件-mutations(三)

272 阅读2分钟

在前面,我们已经实现了Vuex中的store全局共享和getters,现在,我们来实现一下mutations

有了前面实现getters的经验,现在再来完成mutations简直是如鱼得水,轻而易举... 于是我们很快写出下面的代码:

class Store{
  constructor(options){
    this.data = options.state;
    let getters = options.getters || {}
    this.getters = {}
    // mutations
    let mutations = options.mutations || {}
    this.mutations = {}
    Object.keys(mutations).forEach((key) => {
      this.mutations[key] = (payload)=>{
        mutations[key](this.state,payload)
      }
    })
    
    // 把getter对象上的属性全部绑定到this.getter上
    Object.keys(getters).forEach((key) => {
      Object.defineProperty(this.getters, key, {
        get: () => getters[key](this.state)
      })
    })
  }
  get state(){
      return this.data
  }
  commit(mutationType,payload){
      this.mutations[mutationType](payload)
  }
}

现在来测试一下我们的代码:

let store = new Store({
    state:{
       name:'iamsmiling' 
    },
    getters:{
        getName(state){
            return state.name   
        }
    },
    mutations:{
        modifyName(state,payload){
            state.name += payload
        }
    }
})

store.mutations.modifyName(',never give up')  
console.log(store.getters.getName) // 输出结果为"iamsmiling,never give up"

Vuex中的mutations相比,要实现上面的效果,官方调用mutations是采用以下方式,

store.commit('modifyName',',never give up')

接下来,我们也来实现以下commit函数,其实实现也很简单:

class Store{
  ... //
  commit(mutationType,payload){
      this.mutations[mutationType](payload)
  }
  get state(){
      return this.data
  }
}

我们再来测试一下:

store.commit('modifyName',',never cry')
console.log(store.getters.getName) // 输出结果为"iamsmiling,never cry"

现在commit方法也实现了,但还有一个重要问题没有解决,就是我们修改了state的值,页面数据还没有发生变化。

(敲黑板),注意了!!!

我们已经知道Vue中的data全部都是Observer对象,只要数据发生变化,页面就会发生变化,因此,我们要做的其实很简单,就是把state定义到Vue实例中的data中去。

那我们具体该怎么做呢?

import Vue from 'Vue'
class Store{
  constructor(options){
    this._vm = new Vue({
        data:options.state
    })
    let getters = options.getters || {}
    this.getters = {}
    // mutations
    let mutations = options.mutations || {}
    this.mutations = {}
    Object.keys(mutations).forEach((key) => {
      this.mutations[key] = (payload)=>{
        mutations[key](this.state,payload)
      }
    })
    
    // 把getter对象上的属性全部绑定到this.getter上
    Object.keys(getters).forEach((key) => {
      Object.defineProperty(this.getters, key, {
        get: () => getters[key](this.state)
      })
    })
  }
  get state(){
      return this._vm
  }
  commit(mutationType,payload){
      this.mutations[mutationType](payload)
  }
}

未完待续...