一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
学习Vue响应式原理-数据劫持和模板解析
引言
平时一直在用 Vue,也知道 Vue2 中的响应式原理。
它是采用 数据劫持 结合 发布订阅者 模式,通过 Object.defineProperty 来劫持各个属性的 getters 和 setters。当我们的数据发生改变的时候,发布消息给订阅者,触发相应的回调。
可是什么是数据劫持?数据劫持它的内部发生了什么?劫持后又做了什么呢?
数据劫持-Observer
数据劫持,在 Vue2 的源码中主要是通过 Observer 这个类来处理的。
它内部的 walk 函数接受一个主要的参数,就是我们的数据对象 data 值,之后通过 Objcet.keys(data) 来遍历获取 data 对象中的每个 key 值组成一个数组。
walk(data) {
Object.keys(data).forEach((key) => {
this.defineReactive(data, key, data[key])
})
}
将这个数组进行遍历,内部再通过 defineReactive 函数进行操作,这个函数接受3个主要参数 (data,key,value)。通过我们熟悉的 Object.defineProperty 来进行处理
defineReactive(data, key, value) {
Object.defineProperty(data, key, {
get() {
return value
}
set(newVal) {
value = newVal
}
}
到这里,就可以监听到一个数据的变化。我们的数据劫持操作 暂时 处理完。之后进行编译,将我们的模板进行解析。
模板解析- Compile
这一步是比较重要的,主要是将 v-modal 与我们模板中的变量 进行绑定。
在我们的 Compile 中创建文档碎片 createDocumentFragment,通过 js 的方式创建 node 节点。
遍历我们的 node 节点,判断节点种的 nodeType 类型,总共大概 12 种类型。根据不同的类型进行处理。
- 这里说下我们的元素节点 nodeType 值 为 1
获取该节点的 attributes ,来得到一个 类数组
-
类数组 不能直接使用我们的常规数组方法,例如 forEach,filter 等。
-
数组 和 类数组 的区别
-
相同点:
-
都可以通过下标的形式获取到每个元素的值
-
都有 length
-
-
不同点:
-
数组的类型是 Array
-
类数组类型是 Object
-
-
转化
通过 Array.from 将 类数组,转化为 数组
-
之后对我们的节点进行 addEventListener 监听,将输入的 e.target.value 赋值给我们的 data 即可。
总结
学习了 Vue2 中的 数据劫持 和 模板解析的过程。