vuex-modules 中namespaced 为什么只对同名的getter有影响?

645 阅读2分钟

前言:

在我们vue项目的数据结构比较复杂的时候,我们会使用Vuex来管理我们的项目

Vuex提供了很好的状态管理模式同时它还支持我们传入子module,来对数据做整理区分,我们的每一个module 都有一个namespaced 数据,那么它有什么用处呢?

关于module的使用

 egconst moduleA = {
  namespaced: true,
  state: {
    count: 2
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      setTimeout(() => {
        context.commit('increment')
      }, 1000)
    }
  },
  getters: {
    computedCount (state) {
      return state.count + 1
    }
  }
}
const moduleB = {
  namespaced: true,
  state: {
    count: 3
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      setTimeout(() => {
        context.commit('increment')
      }, 1000)
    }
  },
  getters: {
    computedCount (state) {
      return state.count + 1
    }
  }.
}

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  },
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      setTimeout(() => {
        context.commit('increment')
      }, 1000)
    }
  },
  getters: {
    computedCount (state) {
      return state.count + 1
    }
  }
})
   

其实namespaced 是为了帮助我们区分module更好、方便的管理我们的数据,他会自动帮助我们给module中的方法拼接上我们的key

问题:

有些同学在使用过程中发现,如果我们的子module的namespaced 设置为false 或者不设置的话 在同名情况下我们的getters方法定义会有冲突报错,但是action 和 mutation 不会,而且当我们调用的时候,它会两个定义的方法都执行?这是为什么呢?

解析

其实vuex在注册我们传入的这些方法时,对mutations/actions 和 getters 做了不同的处理,废话不多说,上源码

function registerMutation (store, type, handler, local) {
  const entry = store._mutations[type] || (store._mutations[type] = [])
  entry.push(function wrappedMutationHandler (payload) {
   // ...
  })
}

// actions
function registerAction (store, type, handler, local) {
  const entry = store._actions[type] || (store._actions[type] = [])
  entry.push(function wrappedActionHandler (payload, cb) {
    // ...
  })
}

可以看到我们的mutation 和 我们的action 都会push到一个entry的数组中 而我们的getters 是直接把方法取出来赋值给了_wrappedGetters

function registerGetter (store, type, rawGetter, local) {
  //... 
  store._wrappedGetters[type] = function wrappedGetter (store) {
    // ... 
  }
} 

总结:

vuex 对getter注册后,最终是一个functioin 。 而我们的actions 和 mutations 是一个Array, 所以getter如果同名会报错,而actions 和 mutations 同名会指向entry数据( function 集合),执行的时候同步依次执行。