文章目录
vue源码分析总结
MVVM框架基本实现原理
- 数据代理
- 模板解析
- 数据绑定
相关函数:
- 将伪数组转为真数组:
[].slice.call(arr)
node.nodeType
: 得到结点类型(document
,element
,attribute
,text
)Object.defineProperty(obj, propertyName, props)
: 给对象添加属性Object.keys(obj)
: 得到对象自身可枚举属性组成的数组 (IE8不支持)obj.hasOwnProperty(prop)
: 判断prop
是否是obj
的自身属性DocumentFragment
: 文档碎片(高效批量更新多个结点) 内存中保存n
个element
的容器对象
数据代理:
- 通过一个对象代理另一个对象来操作此对象的数据
Vue
数据代理: 通过vm
对象来代理data
对象中所有属性的操作(get/set
)- 用到的是准备中的
3
和4
特性
模板解析(编译):
基本流程:
- 将
el
的所有子结点取出, 添加到一个新建的文档fragment
对象中 - 对
fragment
中所有层次的子结点再内存中递归进行编译解析处理 - 将解析处理后的元素塞回页面
- 用到特性
6
和1
大括号表达式解析
- 根据正则对象得到匹配出的表达式字符串: 子匹配
/RegExp.$1
- 从
data
中取出表达式对应的属性值 - 将属性值设置为文本结点的
textContent
事件指令解析:
- 从指令中取出事件名
- 根据指令的值从
methods
中得到对应的事件处理函数对象 - 给当前结点绑定指定事件名和回调函数的
dom
事件监听 - 指令解析完后,移除指令属性
一般指令解析:
- 得到指令名和智力高表达式
- 从
data
中根据表达式得到对应的值 - 根据指令名确定需要操作元素结点的什么属性
- 将得到的表达式的值设置到对应的属性上
- 移除元素的指令属性
数据绑定:
- 利用数据劫持来实现数据绑定的效果.
- 通过
defineProperty()
来监视data
中所有属性(任意层次,递归实现)数据的变化,一旦变化Dep
就发出通知更新界面 - 用到
3
和4
特性
observe(data, this)
- 被观察者必须是一个对象
- 实现数据劫持
- 遍历所有数据,创建
Dep
- 给
data
重新定义属性,添加set/get
方法 - 建立
Dep
和Wacter
之间关系 - 监听新值变化,
Dep
发出订阅通知,遍历所有相关wacter
进行更新 wacter
调用回调函数更新界面
wacter(data)和Dep
compile
编译解析表达式期间创建wacter
监视,每一个表达式就对应一个监视器Dep
: 初始化时给data
的属性进行数据劫持时创建,与data
中的属性一一对应Dep
和wacter
之间的关系是多对多
双向数据绑定:
- 双向数据绑定是建立在单项数据绑定的基础之上
- 在解析v-model指令时,给当前元素添加input的监听
- 当input等value值发生变化时,将最新的值赋值给当前表达式所对应的data属性,从而更新页面