对于 Vuex 源码的解析
统一数据管理 数据响应式托管 向外暴漏方法原理
Vuex 概述
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。在开发当中,运用 Vuex 统一管理我们的资源,使得开发更明确,适合用在中大型项目。
tips:本文不对 Vuex 的使用做叙述,只对 Vuex 源码进行解析,以下跳转 Vuex 官方中文文档:https://vuex.vuejs.org/zh/
Vuex 状态图与源码结构
Vuex-install
我们知道,Vue 在调用 Vue.use()安装插件时,即会调用安装插件的方法。
而在 Vuex 中,则是调用如下方法:
1 | // 暴露给外部的插件install方法,供Vue.use调用安装插件 |
其中,applyMixin(Vue)会根据 Vue 的版本,将 vuexinit 方法 mixin 到 Vue 的 beforeCreate 钩子函数列表中,在 Vue 实例化的时候调用,从而达到实例化我们的 store 的目的。而且,在 vuexinit 方法中,会判断当前 vue 组件是不是根组件,是,则直接赋值$store,不是,则通过 options 中的 parent 获取父组件的 store 引用,这样每个组件都可以获取到了同一份内存地址的 Store 实例,于是我们可以在每一个组件中访问全局的 Store 实例了。
1 | /** |
看完 vuex-install,我们再看 Store 内部定义了一些什么
Vuex class Store
首先,我们看一看构造函数 contructor()
构造函数中,初始化了我们要用到的内部变量,并且通过 installModule 初始化了 module,通过 resetStoreVM 新建一个 Vue 对象,使用 Vue 内部的响应式实现注册 state 以及 computed
1 | /** |
然后我们来看 installModule,其主要作用就是为 module 加上 namespace 命名空间(如果有),注册 mutation,action,getter,同时递归安装所有子 module
1 | // 初始化module |
然后我们看到 register 注册 action 和 mutation 时,巧妙地用 call()将作用域绑定到 store 实例上,并且暴露 state 等我们需要的内部参数。
1 | // 遍历注册mutation |
接着,再看到 resetStoreVM 中通过新建 Vue 对象实现响应式注册 state 和 computed
1 | function resetStoreVM(store, state, hot) { |
同时,我们都知道 Vuex 支持严格模式,即只能通过 mutation 修改 vuex 状态,他的原理很简单,是通过 store 实例的 vm 实例观察 state,并判断_committing,而在 commit 调用方法前,修改_committing 的值以达到监视效果,两部分的源码如下:
1 | // Vuex执行严格模式下,$watch观察state,保证所有state的操作必须通过mutation实现 |
1 | // 在调用fn()前,修改this._committing,使得严格模式下内部监听state起作用 --function enableStrictMode |
接着我们看到 Vuex 暴露给外部的 dispatch 和 commit 方法,供外部 vue 实例调用 mutation 和 action:
1 | // 调用mutation的commit方法 |
除了满足基本使用的 dispatch 和 action,向外暴露的还有:subscribe,watch, registerModule,unregisterModule 等,解析如下
1 | /** |
结尾
可以看到,Vuex 的实现原理很多地方用到了 Vue 的响应式原理,甚至直接在内部注册了 Vue 实例,其中 call()的引用绑定作用域也是用得很妙,但在我觉得,运用箭头函数进行组件调用时的作用域绑定也可以实现功能。
总结不易,希望能帮到大家哦!!!
编者 github 地址:传送.
也欢迎和我一起讨论学习:
微信号:carfiedfeifei
qq:1073490398