作为不变式,我想确保根据JSON模式,我的vuex存储(实际上是模块之一)中的状态必须始终有效。由于突变是对状态的原子操作,因此应在突变函数的末尾进行验证。
我考虑的一个选择是在每个突变中放入一些代码,以实现这种不变性。因此,每个突变都将如下所示:
const setPostTitle = (state, { title }) {
const postBefore = _.deepClone(state.post)
state.post.title = title
if (!validate(state.post)) {
state.post = postBefore
}
}
我可以将其封装到一个更高阶的函数中,但是每个人都需要注意将其添加到使state.post
上的任何内容发生突变的每个方法中。
我认为另一种选择是使用插件,但是仅商店支持插件,而模块不支持插件(请参阅https://github.com/vuejs/vuex/issues/467)。无论如何,这种解决方案看起来大概是这样的:
export const validatePostPlugin = store => {
let lastValidPostState = {}
store.subscribe((mutation, state) => {
if (!validate(state.post)) {
console.error('Validation failed')
store.commit('setPost', lastValidPostState)
} else {
lastValidPostState = _.deepClone(state.post)
}
})
}
我不喜欢它,因为它总是需要保存整个状态的副本(这里并不重要,但可能确实很大),并且如果验证失败,它也可以完全替换发布状态。
有更好的方法吗?