学习Vue响应式原理-数据劫持和模板解析

225 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

学习Vue响应式原理-数据劫持和模板解析

引言

平时一直在用 Vue,也知道 Vue2 中的响应式原理。

它是采用 数据劫持 结合 发布订阅者 模式,通过 Object.defineProperty 来劫持各个属性的 getterssetters。当我们的数据发生改变的时候,发布消息给订阅者,触发相应的回调。

可是什么是数据劫持?数据劫持它的内部发生了什么?劫持后又做了什么呢?

数据劫持-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 ,来得到一个 类数组

  • 类数组 不能直接使用我们的常规数组方法,例如 forEachfilter 等。

  • 数组类数组 的区别

    • 相同点:

      • 都可以通过下标的形式获取到每个元素的值

      • 都有 length

    • 不同点:

      • 数组的类型是 Array

      • 类数组类型是 Object

    • 转化

      通过 Array.from类数组,转化为 数组

之后对我们的节点进行 addEventListener 监听,将输入的 e.target.value 赋值给我们的 data 即可。

总结

学习了 Vue2 中的 数据劫持 和 模板解析的过程。