• Vue2数据双向绑定的原理(Object.defineProperty)


            首先我们得了解一些MVVM模型, Vue的作者在看到MVVM模型之后, 受到了启发, 开发出了Vue中所特有的模型.

            M: 代表着模型层(Model) 就是data中的数据(一般js对象), V: 代表着视图层(View) 就是DOM元素, VM: 代表着模型层和视图层的链接桥梁 也就是Vue实例.

            

            从这个图中间的两个箭头可以看出来, Vue总共做了两件事:

    • 将data中的数据(一般js对象, 因为data中renturn出来了一个对象), 建设到了DOM元素上.
    • 监听DOM的改变动态的修改data中的数据.

            我们在data中定义的成员都会被挂载到Vue的实例Vm上面, 只要在模板(template)里面进行修改data中的数据, 都会触发视图的改变.

            但是这是有一个前提的, 就是data中所有的成员都需要通过Object.defineProperty进行事件属性拦截, 简答的来说就是他通过Object.defineProperty这个属性将说有成员设置成响应式的.

    现在就来介绍一下Object.definProperty:

    • 第一个参数: 需要动态添加成员的对象(target)
    • 第二个参数: 动态添加到目标对象(target)上的属性(property)
    • 第三个参数: 配置项(description), 其中有enumerable、configurable、writable、value、get和set定义的对象.

    不要着急哈, 现在来一点一点的了解:

    • 先来对比一下动态添加的属性, 和直接将属性写入对象中有什么区别

            很容易的可以看出两个"age"属性颜色是不同的, 使用Object.defineProperty方法添加的是不可以枚举的.

            枚举的意思就是不能被遍历的, 举个栗子:

    直接添加:

     

     

     动态添加:

     

     

    • 再来说一下enumerable、configurable、writable、value这几个成员是如何使用的:
    1. value是动态添加那个属性的属性值
    2. enumerable将它的属性这设置为true的话, 那么动态添加的属性就允许枚举, 默认为false
    3. configurable将它的属性这设置为true的话, 那么动态添加的属性就允许删除, 默认为fasle
    4. writable将它的属性这设置为true的话, 那么动态添加的属性就允许修改, 默认为false

            上述来看, Object.defineProperty条条框框的很多, 很麻烦的样子; 其实不然, 它是一种高级的用法, 可以对属性添加控制.

            不像手动添加属性那样随意, 我们可以对属性更好的控制.

    • 现在就要开始着重的介绍set和get属性了, 数据代理和computed计算属性都是使用的这个底层原理来实现的, 上代码:
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. <div>
    11. <!-- 发布者 -->
    12. <input type="text" class="Publisher">
    13. <!-- 订阅者 -->
    14. <div class="Subscriber">我是订阅者</div>
    15. </div>
    16. <script>
    17. // 目标对象
    18. let Target = {}
    19. let ipt = document.querySelector('.Publisher')
    20. let div = document.querySelector('.Subscriber')
    21. Object.defineProperty(Target, 'msg', {
    22. get() {
    23. return console.log('有人访问了Target.msg的值')
    24. },
    25. set(value) {
    26. console.log('有人修改了Target.msg的值', value)
    27. div.innerHTML = value
    28. }
    29. })
    30. // 观察者
    31. ipt.addEventListener('input', (e) => {
    32. Target.msg = e.target.value
    33. })
    34. </script>
    35. </body>
    36. </html>

    原理: 

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

    什么是数据劫持

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

    发布者模式 / 订阅者模式

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

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

  • 相关阅读:
    腾讯云三年轻量2核4G5M服务器优惠价格(3年566元)
    设计模式之适配器模式
    深入理解 JVM 之——垃圾回收与内存分配策略
    Oracle 可传输表空间(Transportable Tablespace)
    touchGFX综合学习十四、基于cubeMX、正点原子H750开发版、RGB4.3寸屏移植touchGFX完整教程+工程(二)
    Python实战项目:吃金币(源码分享)(文章较短,直接上代码)
    使用Python的requests库与chatGPT进行通信
    【计算机毕业设计】旅游网站ssm源码
    windows 下载安装 mysql
    MySQL 索引
  • 原文地址:https://blog.csdn.net/weixin_48524561/article/details/125539827