• 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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
  • 相关阅读:
    金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测股票价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)
    【源码系列#05】Vue3响应式原理(Ref)
    10种新型网络安全威胁和攻击手法
    MySQL使用ReplicationConnection导致的连接失效分析与解决
    Windows Update MiniTool 20.12.2016 控制Window更新下载及使用教程
    Log4j漏洞反弹shell CVE-2021-44228 Apache Log4j 远程代码执行漏洞复现
    【数据结构-字符串 四】【字符串识别】字符串转为整数、比较版本号
    安全文件传输如何进行管控,从而促进业务的有序发展?
    前端学习路线(三)
    文档 + 模型
  • 原文地址:https://blog.csdn.net/weixin_48357279/article/details/125435507