vue的源码分析

说明

1)分析 vue 作为一个 MVVM 框架的基本实现原理

数据代理

模板解析

数据绑定

2)不直接看 vue.js 的源码

3)剖析 github 上某基友仿 vue 实现的 mvvm 库

4)地址: https://github.com/DMQ/mvvm

准备知识

1)[].slice.call(lis): 将伪数组转换为真数组

2)node.nodeType: 得到节点类型

3)Object.defineProperty(obj, propName, {}): 给对象添加/修改属性(指定描述符)

configurable: true/false 是否可以重新 define

enumerable: true/false 是否可以枚举(for..in / keys())

value: 指定初始值

writable: true/false value 是否可以修改

get: 回调函数, 用来得到当前属性值

set: 回调函数, 用来监视当前属性值的变化

4)Object.keys(obj): 得到对象自身可枚举的属性名的数组

5)DocumentFragment: 文档碎片(高效批量更新多个节点)

6)obj.hasOwnProperty(prop): 判断 prop 是否是 obj 自身的属性

数据代理

1)数据代理: 通过一个对象代理对另一个对象(在前一个对象内部)中属性的操作(读/写)

2)vue 数据代理: 通过 vm 对象来代理 data 对象中所有属性的操作

3)好处: 更方便的操作 data 中的数据

4)基本实现流程

a.通过 Object.defineProperty()给 vm 添加与 data 对象的属性对应的属性描述符

b.所有添加的属性都包含 getter/setter

c.getter/setter 内部去操作 data 中对应的属性数据

模板解析

模板解析的基本流程

1)将 el 的所有子节点取出, 添加到一个新建的文档 fragment 对象中

2)对 fragment 中的所有层次子节点递归进行编译解析处理

a.对大括号表达式文本节点进行解析

b.对元素节点的指令属性进行解析

*事件指令解析

*一般指令解析

3)将解析后的 fragment 添加到 el 中显示

模板解析(1): 大括号表达式解析

1)根据正则对象得到匹配出的表达式字符串: 子匹配/RegExp.$1 name

2)从 data 中取出表达式对应的属性值

3)将属性值设置为文本节点的 textContent

模板解析(2): 事件指令解析

1)从指令名中取出事件名

2)根据指令的值(表达式)从 methods 中得到对应的事件处理函数对象

3)给当前元素节点绑定指定事件名和回调函数的 dom 事件监听

4)指令解析完后, 移除此指令属性

模板解析(3): 一般指令解析

1)得到指令名和指令值(表达式) text/html/class msg/myClass

2)从 data 中根据表达式得到对应的值

3)根据指令名确定需要操作元素节点的什么属性

* v-text---textContent 属 性

* v-html---innerHTML 属性

* v-class--className 属性

4)将得到的表达式的值设置到对应的属性上

5)移除元素的指令属性

数据绑定

数据绑定

一旦更新了 data 中的某个属性数据, 所有界面上直接使用或间接使用了此属性的节点都会更新

. 数据劫持

1)数据劫持是 vue 中用来实现数据绑定的一种技术

2)基本思想: 通过 defineProperty()来监视 data 中所有属性(任意层次)数据的变化, 一旦变化就去更新界面

. 四个重要对象

1)Observer

a.用来对 data 所有属性数据进行劫持的构造函数

b.给 data 中所有属性重新定义属性描述(get/set)

c.为 data 中的每个属性创建对应的 dep 对象

2)Dep(Depend)

a.data 中的每个属性(所有层次)都对应一个 dep 对象

b.创建的时机:

*在初始化 define data 中各个属性时创建对应的 dep 对象

*在 data 中的某个属性值被设置为新的对象时

c.对象的结构

{

id, // 每个 dep 都有一个唯一的 id

subs //包含 n 个对应 watcher 的数组(subscribes 的简写)

}

d.subs 属性说明

*当 watcher 被创建时, 内部将当前 watcher 对象添加到对应的 dep 对象的 subs 中

*当此 data 属性的值发生改变时, subs 中所有的 watcher 都会收到更新的通知,从而最终更新对应的界面

3)Compiler

a.用来解析模板页面的对象的构造函数(一个实例)

b.利用 compile 对象解析模板页面

c.每解析一个表达式(非事件指令)都会创建一个对应的 watcher 对象, 并建立 watcher 与 dep 的关系

d.complie 与 watcher 关系: 一对多的关系

4)Watcher

a.模板中每个非事件指令或表达式都对应一个 watcher 对象

b.监视当前表达式数据的变化

c.创建的时机: 在初始化编译模板时

d.对象的组成

{

vm,   //vm 对象

exp,  //对应指令的表达式

cb,    //当表达式所对应的数据发生改变的回调函数

value, //表达式当前的值

depIds //表达式中各级属性所对应的 dep 对象的集合对象

      //属性名为 dep 的 id, 属性值为 dep

}

5)总结: dep 与 watcher 的关系——多对多

a.data 中的一个属性对应一个 dep, 一个 dep 中可能包含多个 watcher(模板中有几个表达式使用到了同一个属性)

b.模板中一个非事件表达式对应一个 watcher, 一个 watcher 中可能包含多个 dep(表达式是多层: a.b)

c.数据绑定使用到 2 个核心技术

* defineProperty()

* 消息订阅与发布

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容