本文将以代码 + 注释的方式讲解vuex的实现
在开始之前,我们先看一个vuex的使用举例
我们把基本的功能都使用到了,那么接下来我们来看一下vuex中都做了什么
vuex初始化过程
vuex的实现过程
- 使用vue.mixin混入beforeCreated生命周期,注入$store字段赋值vuex.Store实例
- 初始化用户相关配置(state、actions、mutations、getters、modules)
- 根节点相关的配置(state、actions、mutations、getters)命名为root
- modules下相关配置(state、actions、mutations、getters)以树形结构存在root module的 _children 内
- 所有的module挂载到 store 实例的 _modulesNamespaceMap 字段
- actions、mutations、getters以函数名 + 命名空间为key,具体函数为value分别挂载到 store 实例的 _actions、_mutations、_wrappedGetters 字段可以直接访问
- 初始化用户响应式vm实例
- 通过vue.computed计算属性,实现用户getter方法(每次调用都会动态计算state)
vuex注册
在上面的举例中,首先我们注册了vuex插件
Vue.use 会调用 Vuex 的 install 方法(vue开发插件),我们看一下 vuex 的 install 的方法实现:
// 文件路径:/src/store.js => install 函数
我们注意到 vuex 中使用到一个 Vue 全局字段,在 install 的时候会先判断是否重复注册,防止重复注册。
接下来调用了 applyMixin 方法:
在 applyMixin 方法中,首先获取 vue 的版本号,通过这一步,我们可以发现 vuex 分别为 vue1 和 vue2 做了对应的支持。因为现在都在使用 vue2,我们只看 vue2 支持部分,这里使用 Vue.mixin 在 vue 实例的 beforeCreate 生命周期之前执行 vuexInit 方法。
vuexInit 方法的实现:
- 获取 vue 实例的配置项 vue.$options
- 如果配置项中含有 store 字段(开头举例时声明的 store 变量)
- 当前 vue 实例(this)赋值 $store 字段为 配置项的 store 字段,如果 store 字段为函数则执行赋值返回结果,其他情况直接赋值
- 如果配置项不包含 store 字段,且当前实例有父级实例、父级实例已声明 $store 字段
- 当前 vue 实例(this)赋值 $store 字段为 父级实例的 $store 字段
走到这一步,我们完成了vuex插件的注册操作。
vuex实例化
我们在注册 vuex 插件的注册之后,实例化了 Vuex.Store。
我们看一下 new Vuex.Store 实例化都做什么事情。
// 文件目录:/src/store.js => class Store
主要步骤:
- 如果之前未注册 vuex 插件,则注册 vuex 插件
- 初始化module
- 初始化dispatch函数,也就是我们常用的this.$store.dispatch
- 初始化commit函数,也就是我们常用的this.$store.commit
- 初始化根节点的module
- 初始化vue响应式
- 注册插件
- 初始化vue开发者工具
Module
我们声明的 state、mutations、actions、getters 的组合为一个 Module(常见为命名空间)
// 文件目录:/src/module/module.js
注册actions、mutations、getters
dispatch函数
// 文件目录:/src/store => class Store => dispatch
Commit函数
// 文件目录:/src/store => class Store => commit
工具函数
helper函数
mapState函数 & mapGetters函数
使用示例
实现代码:mapState
实现代码:mapGetters
mapMutations函数 & mapActions函数
使用示例
实现代码:mapActions
实现代码:mapMutations
|