Vue对象的深层劫持详细讲解

作者:BraveWangDev 时间:2024-04-26 17:40:20 

一,前言

上篇,主要介绍了在 Vue 的数据初始化流程中,对象属性的单层劫持是如何实现的

回顾一下,主要涉及以下几个核心点:

  • data 为函数和对象的处理,及当 data 为函数时的 this 指向问题

  • Observer 类:对数据进行观测

  • walk 方法:遍历 data 属性(对象属性遍历)

  • defineReactive 方法:利用 Object.defineProperty 实现数据劫持

本篇,继续对 data 数据进行初始化操作,对象属性的深层劫持

二,对象属性的深层观测问题

1,抛出问题

当前版本的代码逻辑:

如果,data 对象中的属性,还是一个对象(称为obj)

那么,这个对象(obj)中的属性是不会被观测的(目前所说的观测还仅仅停留在数据劫持阶段)

就是说,当前仅实现了对 data 对象中属性的单层劫持,嵌套对象不会被深层劫持

2,测试问题

<script>
 let vm = new Vue({
   el: '#app',
   data() {
     // data函数返回的对象中,obj属性为一个对象,它的属性不会被观测
     return { message: 'Hello Vue', obj: { key: "val" } }
   }
 });
</script>

3,查看结果

Vue对象的深层劫持详细讲解

new Vue 时,传如的 options 选项中的 data 函数,

data 函数中,属性 obj 的值依然是一个对象 { key: &ldquo;val&rdquo; }

对象 { key: &ldquo;val&rdquo; } 中的 key,此时没有被添加 get 和 set 方法,说明 key 没有被劫持

三,对象属性深层观测的实现

1,实现思路

TODO:需要先回顾一下,对象属性单层观测的流程

有了 data 对象单层观测的经验,对象属性 obj 深层劫持就简单多了

当对象属性 obj 即将被 Object.defineProperty 劫持时,

再对 obj 对象做一次&ldquo;对象的单层劫持&rdquo;

更深层的对象属性劫持,就是在递归执行&ldquo;对象的单层劫持&rdquo;

即:当属性为对象类型时(非 null)

继续进行 observe 观测,observe 的递归就实现了对象属性的深层劫持

2,代码逻辑

function defineReactive(obj, key, value) {
 observe(value);// 递归实现深层观测
 Object.defineProperty(obj, key, {
   get() {
     return value;
   },
   set(newValue) {
     if (newValue === value) return
     value = newValue;
   }
 })
}

TODO:需要突出递归的逻辑

四,data 相关优化

TODO:结合对象属性观测的特点,介绍 data 的相关优化

五,结尾

本篇主要实现了 Vue 数据初始化流程中,对象属性的深层劫持,核心思路就是递归;

  • 通过data = isFunction(data) ? data.call(vm) : data;处理后的data一定是对象类型

  • 通过data = observe(data)处理后的 data 就实现了数据的响应式(目前只有劫持)

  • observe 方法最终返回一个 Observer 类

  • Observer类初始化时,通过 walk 遍历属性

  • 对每一个属性进行 defineReactive(Object.defineProperty)就实现对象属性的单层数据劫持

  • 在 defineReactive 中,如果属性值为对象类型就继续调用 observe 对当前的对象属性进行观测(即递归步骤 3~5),这样就实现了对象属性的深层数据劫持

下一篇,数组的劫持

来源:https://blog.csdn.net/ABAP_Brave/article/details/128566839

标签:Vue,对象,深层,劫持
0
投稿

猜你喜欢

  • XML正在接管Web服务 成为SOA的基础

    2008-09-05 17:21:00
  • 一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的

    2024-01-17 22:31:24
  • Python实战购物车项目的实现参考

    2021-09-28 11:06:29
  • Python中的super()方法使用简介

    2021-03-06 21:27:35
  • Python简单生成随机姓名的方法示例

    2023-04-26 19:35:58
  • having的用法以及与where区别介绍

    2024-01-17 09:55:44
  • Python IDLE Subprocess Connection Error的简单解决方法

    2022-12-15 04:31:09
  • Python 中如何将十六进制转换为 Base64

    2022-09-07 01:20:14
  • pyqt远程批量执行Linux命令程序的方法

    2023-05-08 15:59:06
  • *.HTC 文件的简单介绍

    2008-11-24 17:36:00
  • Python使用multiprocessing实现一个最简单的分布式作业调度系统

    2022-06-14 07:43:33
  • python的id()函数解密过程

    2023-03-04 00:17:52
  • ajax+asp无限级分类树型结构

    2011-04-02 11:05:00
  • 学python需要去培训机构吗

    2022-02-12 07:46:29
  • python实现AES算法及AES-CFB8加解密源码

    2022-06-14 01:24:01
  • vue实现右键弹出菜单

    2024-05-21 10:17:41
  • JavaScript 各种动画渐变效果

    2008-09-02 10:38:00
  • 关于Python网络爬虫框架scrapy

    2023-03-17 17:02:50
  • Python中bisect的用法

    2023-11-05 08:47:53
  • Python找出最小的K个数实例代码

    2022-09-13 12:21:10
  • asp之家 网络编程 m.aspxhome.com