Vuex 源码:深入 mutation 的更多秘密
2023-10-05 03:31:15
Vuex 规定更改 state 的唯一方法是提交 mutation。这是为了能用 devtools 追踪状态变化。那么,提交 mutation 除了最主要的更改 state,它还做了其它一些什么事情呢?让我们来一探究竟。
初步猜测,store 对象的初始化时将 mutation 注册到 store 对象上。让我们来看看源码:
function store (options = {}) {
const vuex = new Store(options)
if (plugins !== undefined) {
each(plugins, plugin => plugin(vuex))
}
return vuex
}
很明显,store 函数只是调用了 Store 类的构造函数,将传入的参数作为选项传入,然后返回了 Store 实例。我们还需要继续研究 Store 类,才能找到 mutation 被注册的过程。
class Store {
constructor (options = {}) {
// ... 省略部分
const { mutations } = options
if (mutations) {
this._mutations = installModuleMutations(mutations, this, true)
this._wrappedGetters = installModuleGetters(getters, this)
}
// ... 省略部分
}
}
在 Store 类的构造函数中,如果 options 对象中有 mutations 属性,那么就会调用 installModuleMutations 方法来安装 mutation。
function installModuleMutations (mutations, store, checkVuex) {
if (__WEEX__) {
return Vuex.mutations
} else if (checkVuex) {
checkVuexMutations(mutations)
}
const wrappedMutations = {}
each(mutations, (mutation, key) => {
const wrappedMutation = function wrappedMutation (...args) {
handleMutationCall(this, mutation, args)
}
// ... 省略部分
})
return wrappedMutations
}
在 installModuleMutations 方法中,会对 mutation 做一些处理,然后将其包装成一个新函数,最后将新函数存储在 wrappedMutations 对象中。
function handleMutationCall (vm, mutation, args) {
if (vm._committing) {
return
}
vm._committing = true
const res = mutation.apply(vm, args)
vm._committing = false
return res
}
在 handleMutationCall 函数中,会首先检查 vm._committing 属性是否为 true,如果是,则直接返回,不执行 mutation。否则,将 vm._committing 属性设置为 true,执行 mutation,并将执行结果存储在 res 变量中。然后,将 vm._committing 属性设置为 false,并返回 res 变量。
Mutation 是 Vuex 中非常重要的一个概念。它可以帮助我们修改 state,并通过 devtools 来追踪状态变化。通过深入研究 mutation 的源码,我们可以更好地理解 Vuex 的工作原理,并将其应用到我们的项目中。