关于vue的双向数据绑定:MVVM、数据劫持和发布-订阅模式

目录

        1.概述

        2.关于MVVM模式

        3.什么是双向绑定       

        4.发布-订阅模式

        5.双向绑定的核心: Object.defineProperty() 或  Proxy 构造函数

                1. Object.defineProperty()

        6.问题


1.概述

        vue 在实例化的时候,使用 Object.definePropety() 方法或 Proxy 构造函数,对 data 进行 getter 和 setter 的处理。在组件渲染时,若用到 data 里的某个数据,这个数据就会被依赖收集进 watcher 里。当数据更新,如果这个数据在 watcher 里,就会收到通知并更新,否则不会更新——vue 采用 “数据劫持”+“观察者模式(发布者-订阅者模式)”相结合的方式实现了双向绑定——vue 的响应式原理。

2.关于MVVM模式

原文链接2

        MVVM(Model-View-ViewModel)是对 MVC(Model-View-Control)和 MVP(Model-View-Presenter)的进一步改进。

View:视图层(UI 用户界面)
ViewModel:业务逻辑层(一切 js 可视为业务逻辑,也就是前端的日常工作)
Model:数据层(存储数据及对数据的处理如增删改查)
MVVM 将数据双向绑定(data-binding)作为核心思想,View 和 Model 之间没有联系,它们通过 ViewModel 这个桥梁进行交互

        Model 和 ViewModel 之间的交互是双向的,因此 View 的变化会自动同步到 Model,而 Model 的变化也会立即反映到 View 上显示

        当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。

        MVVM框架的的核心就是双向绑定, 其原理是通过 数据劫持+发布订阅模式 相结合的方式来实现的,简单来说就是数据层发生变化的时候,可同布更新视图层,当视图层发生变化的时候,同步更新数据层。

3.什么是双向绑定

原文链接3

        先从单向绑定切入,单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。
        双向绑定就很容易联想到了,在单向绑定的基础上,用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。
        vue的双向绑定指的是数据变化更新视图,视图变化更新数据vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是vue的精髓之处了。

原文链接4   原文链接1

  1. 第一步,“数据劫持”:vue 2.x 用 Object.defineProperty() 方法来实现数据劫持,为每个属性分配一个订阅者集合的管理列表 watcherList ;vue 3.x 用 ES6 的 Proxy 构造函数 来实现数据劫持。通过 DefineProperty 劫持各个数据的 setter getter ,并为每个数据添加一个订阅者列表 watcherList ,这个列表将会记录所有依赖这个数据的组件。响应式后的数据相当于消息的发布者
  2.  第二步,“添加订阅者”:每个组件都对应一个 Watcher 订阅者,当组件渲染函数render执行时,此时会用到data里的响应式数据,触发getter方法,在getter方法中会将本组件的 Watcher 添加到所依赖的响应式数据的订阅者列表 watcherList 中。相当于完成了一次订阅,这个过程叫做“依赖收集”。添加方式包括:v-model 会添加一个订阅者,{{}} 也会,v-bind 也会,只要用到该属性的指令理论上都会。(见问题1、2)
  3. 第三步,“为 input 添加监听事件”:为 input 添加监听事件,事件中改变某响应式数据当响应式数据发生变化时,会触发 setter(见问题3) setter 中调用该数据发布者的发布通知方法,通知订阅者数组 watcherList 循环调用各订阅者 Watcher 的 update() 方法更新视图, 触发组件重新渲染来更新视图(见问题4)。视图层相当于消息的订阅者

双向绑定的实现:数据劫持 + 观察者模式(发布者-订阅者模式)。

       

4.发布-订阅模式

        观察者模式又叫发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

发布-订阅模式的角色有两类:发布者和订阅者

写一个发布-订阅模式:





    
    
    
    Vue的双向数据绑定



    
    
    






缺少数据劫持、Compile的方法,看参考文档

5.双向绑定的核心: Object.defineProperty() 或  Proxy 构造函数

1. Object.defineProperty()

原文链接2

        Object.defineProperty(obj, prop, descriptor) 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

obj:要定义属性的对象;
prop:要定义或修改的属性的名称或 Symbol;
descriptor:要定义或修改的属性描述符;
返回值:被传递给函数的对象;

我们通过 Object.defineProperty 的get方法用来获取值 ,set 方法用来拦截设置值;

6.问题

1.在vue的双向数据绑定中,哪些是订阅者?答:每个组件都对应一个 Watcher 订阅者。
2.在什么时候添加的订阅者?怎么添加的?答:当组件渲染函数render执行时,会将本组件的 Watcher 添加到所依赖的响应式数据的订阅者列表 watcherList 中。
3.怎么劫持到更新的数据以便通知发布者来发布?(怎么监听订阅者的变化从而发布、触发set的原理,即 Object.defineProperty 如何监听数据以触发set)
4.update方法如何触发 组件重新渲染来更新试视图?  答:触发组件的compile渲染方法,进行渲染数据(组件创建新的虚拟dom,新老虚拟dom通过diff算法对比找到差距,以最小的代价更新页面)
5.对应1问题:订阅者是每一个.vue文件组件?还是说是.vue文件中的每个节点?即.vue文件是订阅者还是里面的节点是订阅者?

你可能感兴趣的:(vue.js,javascript,前端)