摘要:为了更清楚的理解它的原理和实现,还是从源码开始读起吧。结构梳理先抛开,的主要源码一共有三个文件,,初始化相关用到了和我们使用创建的实例并传递给的根组件。这个方法的第一个参数是构造器。的中,在保证单次调用的情况下,调用对构造器进入了注入。
原文链接
Vuex 作为 Vue 官方的状态管理架构,借鉴了 Flux 的设计思想,在大型应用中可以理清应用状态管理的逻辑。为了更清楚的理解它的原理和实现,还是从源码开始读起吧。总共 1000 多行的代码,读起来也相对轻松。
cloc src/ ------------------------------------------------------------------ Language files blank comment code ------------------------------------------------------------------ JavaScript 5 53 141 389 ------------------------------------------------------------------ SUM: 5 53 141 389 ------------------------------------------------------------------ cloc test/ ------------------------------------------------------------------ Language files blank comment code ------------------------------------------------------------------ JavaScript 5 62 30 793 ------------------------------------------------------------------ SUM: 5 62 30 793 ------------------------------------------------------------------结构梳理
先抛开 middlewares,Vuex 的主要源码一共有三个文件:
file | intro |
---|---|
index.js | Class Store, install,... |
override.js | 初始化 Vuex |
util.js | 相关 util(用到了 getWatcher 和 getDeep) |
我们使用 Store 创建 Vuex 的实例并传递给 Vue 的根组件。主要包含了 state 和 mutation。Store 创建了一个 data 为 state 的 Vue 实例,使用了 ES6 Class 的 get 和 set 对 state 做了映射,对 state 的重新 set 当然是不允许的,get 则映射到了 this._vm._data。
Store 提供了 dispatch 方法来完成对 state 的修改,和想象中的差不多,在 _mutations 里找到对应 type 的 mutation,参数并入 this.state 传参调用。
override作为一个 Vue 的插件,Vuex 需要被这样引入:
import Vue from "vue" import Vuex from "vuex" Vue.use(Vuex)
Vue 的插件应当有一个公开方法 install。这个方法的第一个参数是 Vue 构造器。 Vuex 的 install 中,在保证单次调用的情况下,调用 override 对 Vue 构造器进入了注入。
override 中对 Vue.prototype._init 注入了 vuexInit,vuexInit 会在每个 instance 的 init hook 中调用。
第一步是绑定 store, Vuex 会寻找 options 中的 store 作为实例的 $store,在不存在时则以递归的方式寻找父组件中的 $store,因此在 Vuex 的项目中,store 只需要在根组件中注入即可。
第二步是处理 vuex, 分别处理其中的 getters 和 actions, 以 example/counter/Counter.vue 为例:
gettersVuex 用 Object.defineProperty 为每个 getter 在 vm 上绑定了 data,特别的是 getter 作为单向仅 get 数据流,并不能被 set,所以对应的 setter 为报错用的空函数。而 getter 的原理类似于 computed getter,特别的是使用了 store 的 uniqueId 为标识做了缓存,这样同一个 getter 在所有组件中都会使用相同的 watcher。
setterAction 相对要简单一些,以 $store 作为 action 第一个参数,并将 action 绑定在 instance 上。形成了一个闭环,让 action 访问到 store。
总结Vuex 源码上粗略的分析基本就到这里了,其实很多地方的代码都很值得细细研究,比如 Store 中的 middlewares 可以完成一些神奇的事情,这里就不一一分析了,画了一张图,按源码的思路大概表达下数据流的意思。O(∩_∩)O
+-----------+ | | | Store +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+ | | v |-----------| v | state <<<<<<+ v |-----------| ^ v +>>>>>- distapatch ->>>>+ v ^ +-----------+ v ^ v ^ +--------------------+ v ^ | | v ^ | Component | v ^ | | v ^ |--------------------| v ^ +<<<<<----- $store <------<<<<<+ ^ v |--------------------| ^ v | vuex: { | ^ v | | ^ +>>>>>----- getters: {}, | ^ | | +<<<<<<<<<<<<<<<<<<<<<<<<<<----- actions: {} | | | | } | +--------------------+
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/79444.html
摘要:我们通常称之为状态管理模式,用于解决组件间通信的以及多组件共享状态等问题。创建指定命名空间的辅助函数,总结的功能首先分为两大类自己的实例使用为组件中使用便利而提供的辅助函数自己内部对数据状态有两种功能修改数据状态异步同步。 what is Vuex ? 这句话我想每个搜索过Vuex官网文档的人都看到过, 在学习源码前,当然要有一些前提条件了。 了解Vuex的作用,以及他的使用场景。 ...
摘要:各位看官没看过功能梳理的可以先阅读下源码学习一功能梳理前车之鉴有了源码学习的经验,每次看认真钻研源代码的时候都会抽出一小段时间来大体浏览一遍源代码。大体了解这个源代码的脉络,每个阶段做了什么,文件目录的划分。 各位看官 没看过功能梳理的可以先阅读下Vuex源码学习(一)功能梳理. 前车之鉴 有了vue-router源码学习的经验,每次看认真钻研源代码的时候都会抽出一小段时间来大体浏览一...
摘要:前言本文内容讲解的内容一张思维导图辅助你深入了解源码架构。总结以上内容是笔者最近学习源码时的收获与所做的笔记,本文内容大多是开源项目技术揭秘的内容,只不过是以思维导图的形式来展现,内容有省略,还加入了笔者的一点理解。1.前言 本文内容讲解的内容:一张思维导图辅助你深入了解 Vue | Vue-Router | Vuex 源码架构。 项目地址:github.com/biaochenxuy… 文...
摘要:先看一下创建一个容器存放该模块所有的子模块存放自己未被加工的模块内容。是封装的工具方法,用于遍历对象的。这些方便高效的方法为之后的注册。 没有看过moduleCollection那可不行!Vuex源码学习(四)module与moduleCollection 代码块和截图的区别 代码块部分希望大家按照我的引导一行行认真的读 代码的截图是希望大家能记住图中的结构与方法,下面会对整体进行一...
摘要:自定义自己的模板在使用的过程中,常用的模板只为我们提供最基础的内容,但每次需要新建一个项目的时候就需要把之前项目的一些配置都搬过来,这样就造成挺大的不方便,如果是作为一个团队,那么维护一个通用的模板,我认为是挺有必要的。 自定义自己的vue-cli模板 在使用vue-cli的过程中,常用的webpack模板只为我们提供最基础的内容,但每次需要新建一个项目的时候就需要把之前项目的一些配置...
阅读 3468·2021-09-02 09:53
阅读 1791·2021-08-26 14:13
阅读 2749·2019-08-30 15:44
阅读 1313·2019-08-30 14:03
阅读 1961·2019-08-26 13:42
阅读 3013·2019-08-26 12:21
阅读 1301·2019-08-26 11:54
阅读 1899·2019-08-26 10:46