首先介绍一下什么是vuex的严格模式?
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。也就说想要改变状态,必须要使用mutation函数。
那么vuex是如何实现严格模式的呢?
一、首先要开启严格模式。
const store = new Vuex.Store({
// ...
strict: true
})
用户实例化Store的时候传入strict为true就开启了严格模式
二、接收参数
const {
strict = false
} = options
// strict mode
this.strict = strict
// enable strict mode for new vm
if (store.strict) {
enableStrictMode(store)
}
接收参数,如果strict就调用enableStrictMode方法
三、enableStrictMode实现
function enableStrictMode (store) {
store._vm.$watch(function () { return this._data.$$state }, () => {
if (process.env.NODE_ENV !== 'production') {
assert(store._committing, `do not mutate vuex store state outside mutation handlers.`)
}
}, { deep: true, sync: true })
}
// util.js里提供的
export function assert (condition, msg) {
if (!condition) throw new Error(`[vuex] ${msg}`)
}
这个方法主要有两点,一个是$watch,这个功能是vue提供的,另一个是assert,总结分析就是改变this._data.$$state的时候,store._committing必须为true,否则就警报。接下去就分析store._committing。
四、store._committing分析
this._committing = false
_withCommit (fn) {
const committing = this._committing
this._committing = true
fn()
this._committing = committing
}
刚开始的时候,这个变量设置为false,如果要改变数据包装一个_withCommit方法,执行方法之前,将this._committing设置true,执行完了之后改回false.
五、使用_withCommit封装函数
store._withCommit(() => {
Vue.set(parentState, moduleName, module.state)
})
源码里其他地方也用了_withCommit。
所以vuex实现严格模式的原理就是改变状态的时候,标记一个变量是否为true。