Vue双向绑定的原理

Vue 数据双向绑定原理是通过 数据劫持 + 发布者-订阅者模式 的方式来实现的,首先是通过 ES5 提供的 Object.defineProperty() 方法来劫持(监听)各属性的 getter、setter,并在当监听的属性发生变动时通知订阅者,是否需要更新,若更新就会执行对应的更新函数。

什么是数据劫持

数据劫持比较好理解,通常我们利用Object.defineProperty劫持对象的访问器,在属性值发生变化时我们可以获取变化,从而进行进一步操作。

发布者模式 / 订阅者模式

在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

这里很明显了,区别就在于,不同于观察者和被观察者,发布者和订阅者是互相不知道对方的存在的,发布者只需要把消息发送到订阅器里面,订阅者只管接受自己需要订阅的内容

Object.defineProperty

Object.defineProperty( obj, prop, descriptor )

三个参数:

obj 要定义的对象

prop 要定义或修改的属性名称或 Symbol

descriptor 要定义或修改的属性描述符

属性描述符

get 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 默认为 [undefined] set 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认为 [undefined]


  <!-- 发布者 -->
  <input type="text">
  <!-- 订阅者 -->
  <div class="demo"></div>

  <!-- 观察者 Object.defineProperty(目标对象,目标对象中的属性,{6个属性:set,get,value,枚举,可选值,是否可写}) -->
  <script>
    /* 观察者 */
    let target = {} //目标对象
    Object.defineProperty(target, 'msg', {
      get () { },
      set (value) {
        console.log(value, 5);
        demo.innerHTML = value
        ipt.value = value
      }
    })


    let ipt = document.querySelector('input')
    let demo = document.querySelector('.demo')
    ipt.addEventListener('input', (e) => {
      console.log(e.target.value, 99);
      target.msg = e.target.value
    })

====================================================================================================
    //  vue3的双向绑定原理
    /* Proxy */
    let proxy = new Proxy({}, {
      // set (目标对象,key,value) {
      set (target, key, value) {
        console.log(target, key, value, 888);
        demo.innerHTML = value
        ipt.value = value
      }, // setter
      get () { } // getter  
    })

    let ipt = document.querySelector('input')
    let demo = document.querySelector('.demo')
    ipt.addEventListener('input', (e) => {
      console.log(e.target.value, 99);
      proxy.msg = e.target.value
    })
  </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值