该文章内容节选自团队的开源项目 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 的整体代码并不多,但是却是个值得阅读的项目。如果你在阅读的过程中有什么疑问或者发现了我的错误,欢迎在评论中讨论。
如果你想学习到更多的前端知识、面试技巧或者一些我个人的感悟,可以关注我的公众号一起学习
本文转载自: 掘金