[源码学习] Vue

原文链接

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

我们使用 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 为例:

getters

Vuex 用 Object.defineProperty 为每个 getter 在 vm 上绑定了 data,特别的是 getter 作为单向仅 get 数据流,并不能被 set,所以对应的 setter 为报错用的空函数。而 getter 的原理类似于 computed getter,特别的是使用了 store 的 uniqueId 为标识做了缓存,这样同一个 getter 在所有组件中都会使用相同的 watcher。

setter

Action 相对要简单一些,以 $store 作为 action 第一个参数,并将 action 绑定在 instance 上。形成了一个闭环,让 action 访问到 store。

总结

Vuex 源码上粗略的分析基本就到这里了,其实很多地方的代码都很值得细细研究,比如 Store 中的 middlewares 可以完成一些神奇的事情,这里就不一一分析了,画了一张图,按源码的思路大概表达下数据流的意思。O(∩_∩)O

  +-----------+  |           |  |   Store   +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+  |           |                                   v  |-----------|                                   v  |   state   >>>>- distapatch ->>>>+                             v

^ +-----------+ v
^ v
^ +--------------------+ v
^ | | v
^ | Component | v
^ | | v
^ |--------------------| v
^ +>>>>----- getters: {}, |
^ | |

关键字:vuex, vue.js, flux, store


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部