vuex可以理解成是转为vuejs应用开发的全局状态管理功能,它让状态以一种可被追踪的形式进行变更,方便代码维护。
本文总结下VUEX的实现原理,只说思路,不讲代码。
首先要知道vue中的响应式原理,数据在实例初始化时被劫持。VUEX中的数据也是响应式的,我们看下他是怎么做的。
当项目引入VUEX功能时,会使用VUE的mixin向全局的VUE实例进行混入。在每个vue实例的beforeCreate声明周期中,将store赋值给this.$store
Vue.mixins({
beforeCreate() {
this.$store = store;
......
}
})
这样在全局的vue组件中都可以用this.$store访问到store对象。
查看源码可知,在new Vuex.Store()函数中执行了一个这样的函数。
// src/store.js
function resetStoreVM (store, state, hot) {
// 省略无关代码
Vue.config.silent = true
store._vm = new Vue({
data: {
$$state: state
},
computed
})
}
可以看出,内部创建了一个隐藏的vue实例,我们在store中写入的state成为该vue实例中data里的数据。
我们先回忆下创建store的代码
new Vuex.Store({
state,
getters,
mutations,
actions,
modules
})
我们暂且不考虑actions和modules,其他几个选项和vue实例中的选项对应关系为:
state --- data
getters --- computed
mutations --- methods
我们开发时,dispatch用来触发actions中的方法,commit用来触发mutations中的方法。
其实如果我们直接在mutaitons中写异步方法也是没问题的,state中的数据可以在异步回调中更新。为什么不建议这样做呢?
一般来说执行mutations中的方法,就会触发状态变更,这个时候状态变更是可被追踪的。若在mutations中用异步方法,由于程序没有办法知道数据是在哪个时刻更新的,就没有办法很好的做数据状态跟踪,这违背vuex设计的理念,所以规定大家都不要这么做。