vue 2.x 数据代理 exp

一段示例代码,版本是Vue 2.6.10。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          name: "张三",
          age: 18,
        },
      });
    </script>
  </body>
</html>

首先打印一下vm,观察一下age和name属性(…) ,弹出提示invoke property getter,意思是‘调用属性getter’,也就是说我们看到的name属性值,是被Object.defineProperty()中getter所获取的值。
在这里插入图片描述
获取name值的链路就是,访问vm.name会调用Object.defineProperty()中的getter,从我们定义的data对象中(代理中)获取(读)name值,又或是修改时,从data中修改(写)值。
在这里插入图片描述
现在可以来验证一下以上链路:

  1. 读:用户访问vm.name---->触发getter方法---->将data中name赋值给vm.name
  2. 写:用户修改vm.name---->触发setter方法---->将data中name修改后赋值给vm.name

在这里插入图片描述
getter是比较好验证的,只要打印出来的数据和当时定义的数据一致,就可以确定是数据代理。(??代理了data数据)
在这里插入图片描述
接下来验证setter
在这里插入图片描述
如何判断vm.data.name值有没有发生变化?直接打印data.name是获取不到值的,原因是data只是vm的一个options(配置项),不是全局都可以调用的变量,同理,通过vm.data也是获取不到值
在这里插入图片描述
在这里插入图片描述
我们再返回去打印一下vm,发现一个类似于data的_data数据,但是显示的是’{ob:Observer}'展开发现_data与data中定义的数据一致。
在这里插入图片描述
在这里可以先跳过{ob:Observer}(后面研究),来分析一下‘可能性’?这会不会是,vue把data中的数据,通过vm._data=options.data(可以把options堪称vue的配置项,比如options.el)定义到_data上?
再上一段代码,把data抽离出来,方便验证vm._data=options.data=data这三个等于。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="root">
      <p>姓名:{{name}}</p>
      <p>年龄:{{age}}</p>
    </div>
    <script type="text/javascript">
    let data = {
          name: "张三",
          age: 18,
        },
    const vm = new Vue({
        el: "#root",
        data
    });
    </script>
  </body>
</html>

打印如下,可以发现vm._data 是全等于data的
在这里插入图片描述
我们再打印vm._data.name和vm.name,结果如下,也就是说,其实访问vm.name(访问vm.name也就是从data中取name值,毕竟代码中只有一处定义了name)和访问vm._data.name效果是一样的,只不过更多的是选择vm.name这种方式获取data中的数据。
在这里插入图片描述

  <body>
    <div id="root">
      <p>姓名:{{_data.name}}</p>
      <p>年龄:{{_data.age}}</p>
    </div>
    <script type="text/javascript">
      const vm = new Vue({
        el: "#root",
        data: {
          name: "张三",
          age: 18,
        },
      });
    </script>
  </body>

在这里插入图片描述
接着再去修改vm._data.name的数据,可以发现页面发生相应的变化。
在这里插入图片描述
这时候再通过vm获取name(实际上是data.name)值,会发现data中的数据被修改了
在这里插入图片描述

现在再来验证setter,通过vm修改name,观察data中的name是否会发生改变,
如下图,通过vm修改name值为王五,实际上是调用了setter方法,修改了data中的数据,被vue监测到,页面同步更新(数据代理)。

在这里插入图片描述
图示
在这里插入图片描述
最后说明一点,通过展开vm._data,会发现里面套了娃,实际上里面并不是数据代理,而是vue做了一层数据劫持,以方便实现数据监听,最终达到数据响应式的功能。
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值