该文章内容节选自团队的开源项目 InterviewMap。项目目前内容包含了 JS、网络、浏览器相关、小程序、性能优化、安全、框架、Git、数据结构、算法等内容,无论是基础还是进阶,亦或是源码解读,你都能在本图谱中得到满意的答案,希望这个面试图谱能够帮助到大家更好的准备面试。
Vuex 思想
在解读源码之前,先来简单了解下 Vuex 的思想。
Vuex 全局维护着一个对象,使用到了单例设计模式。在这个全局对象中,所有属性都是响应式的,任意属性进行了改变,都会造成使用到该属性的组件进行更新。并且只能通过 commit 的方式改变状态,实现了单向数据流模式。
Vuex 解析
Vuex 安装
在看接下来的内容前,推荐本地 clone 一份 Vuex 源码对照着看,便于理解。
在使用 Vuex 之前,我们都需要调用 Vue.use(Vuex) 。在调用 use 的过程中,Vue 会调用到 Vuex 的 install 函数
install 函数作用很简单
- 确保 Vuex 只安装一次
- 混入
beforeCreate钩子函数,可以在组件中使用this.$store
1 | 复制代码export function install (_Vue) { |
Vuex 初始化
this._modules
本小节内容主要解析如何初始化 this._modules
1 | 复制代码export class Store { |
接下来看 this._modules 的过程,以 以下代码为例
1 | 复制代码const moduleA = { |
对于以上代码,store 可以看成 root 。在第一次执行时,会初始化一个 rootModule,然后判断 root 中是否存在 modules 属性,然后递归注册 module 。对于 child 来说,会获取到他所属的 parent, 然后在 parent 中添加 module 。
1 | 复制代码export default class ModuleCollection { |
installModule
接下来看 installModule 的实现
1 | 复制代码// installModule(this, state, [], this._modules.root) |
resetStoreVM
接下来看 resetStoreVM 的实现,该属性实现了状态的响应式,并且将 _wrappedGetters 作为 computed 属性。
1 | 复制代码// resetStoreVM(this, state) |
常用 API
commit 解析
如果需要改变状态的话,一般都会使用 commit 去操作,接下来让我们来看看 commit 是如何实现状态的改变的
1 | 复制代码commit(_type, _payload, _options) { |
dispatch 解析
如果需要异步改变状态,就需要通过 dispatch 的方式去实现。在 dispatch 调用的 commit 函数都是重写过的,会找到模块内的 mutation 函数。
1 | 复制代码dispatch(_type, _payload) { |
各种语法糖
在组件中,如果想正常使用 Vuex 的功能,经常需要这样调用 this.$store.state.xxx 的方式,引来了很多的不便。为此,Vuex 引入了语法糖的功能,让我们可以通过简单的方式来实现上述的功能。以下以 mapState 为例,其他的几个 map 都是差不多的原理,就不一一解析了。
1 | 复制代码function normalizeNamespace(fn) { |
最后
以上是 Vue 的源码解析,虽然 Vuex 的整体代码并不多,但是却是个值得阅读的项目。如果你在阅读的过程中有什么疑问或者发现了我的错误,欢迎在评论中讨论。
如果你想学习到更多的前端知识、面试技巧或者一些我个人的感悟,可以关注我的公众号一起学习
本文转载自: 掘金