Vue源码学习(一):数据的双向绑定

我们知道在Vue中,数据的双向绑定在2.0中是通过 Object.defineProperty 来进行数据的监听,劫持对象的访问器,在属性值发生变化时我们可以获取变化,然后根据变化进行后续响应,而在vue3.0则是通过Proxy代理对象进行的。

在Vue2.0中只有该数据是对象才会使用Object.defineProperty,如果是数组,则会把数组的方法重写。

接下来就来简单实现一下Object.defineProperty的双向绑定原理。

首先是对第一层的对象进行双向绑定,通过一个render函数来模拟视图渲染,再定义一个obj对象。并且需要定义一个observer函数,也就是vue中的观察者,来判断这个对象是否为object类型,如果是则对这个对象进行遍历,并将该对象里的每个子元素传给defineReactive函数来进行数据的双向绑定。

function render() {
      console.log("模拟视图渲染了");
    }

    let obj = {
      name: "zmj",
      location: { x: 100, y: 200 }
    };

    function defineReactive(data, key, value) {
      Object.defineProperty(data, key, {
        get() {
          return value
        },
        set(newValue) {
          render()
          value = newValue;
        }
      })
    };

    function observer(obj) {  // 把所有属性定义成set get
      if (typeof obj == "object") {
        for (let key in obj) {
          defineReactive(obj, key, obj[key])
        }
      }
    }

    observer(obj)
    obj.name = "lqb"

在这里插入图片描述

上面的代码只能循环第一层的数据,当我们要改obj.location里的数据时,这个响应式就不起作用了,我们可以这样,通过再调用一次observer,把obj里的子对象的value再传给observer函数,对再进行一次遍历,以达到对第二层数据的深层遍历。

在这里插入图片描述
如果需要将location整个重新赋值,就需要在defineReactive中的set方法再调用一次observer。
在这里插入图片描述

当我们要给一个对象新增属性时,是不会被监控的,这个时候可以用vue给我们的方法,vm.$set 这个方法来给对象新增属性,它的原理也很简单,如下图,也是通过调用defineReactive来给新增的属性加上get、set方法实现。
也可以通过obj.location = {…obj.location, a: 1} 这种方法来实现。
在这里插入图片描述

对于是数组的对象,vue中是将数组的方法进行重写来实现响应式的。
首先我们需要将数组的方法拷贝下来,并放进proto中,这是作为后面原型指向的。之后通过forEach方法循环methods里的方法进行重写,重写的方法中需要调用render函数以及原生的数组方法,原生的方法需要用call改变this的指向。然后在observer函数中判断传入的对象是否为数组,并把传入的对象的原型指向刚刚创建好的proto对象。

在这里插入图片描述
在这里插入图片描述

调用$set方法来改变数组中的内容的原理也很简单,先判断传入的data是否为数组,如果是则通过splice方法更改数组的内容并返回出去。

$set方法不好的地方在于 它不支持数组的长度变化,也不支持数组的内容发生变化,必须通过下面的方法触发更新 或者替换成一个新数组
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值