目录
1.概述
2.关于MVVM模式
3.什么是双向绑定
4.发布-订阅模式
5.双向绑定的核心: Object.defineProperty() 或 Proxy 构造函数
1. Object.defineProperty()
6.问题
vue 在实例化的时候,使用 Object.definePropety() 方法或 Proxy 构造函数,对 data 进行 getter 和 setter 的处理。在组件渲染时,若用到 data 里的某个数据,这个数据就会被依赖收集进 watcher 里。当数据更新,如果这个数据在 watcher 里,就会收到通知并更新,否则不会更新——vue 采用 “数据劫持”+“观察者模式(发布者-订阅者模式)”相结合的方式实现了双向绑定——vue 的响应式原理。
原文链接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
先从单向绑定切入,单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。
双向绑定就很容易联想到了,在单向绑定的基础上,用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。
vue的双向绑定指的是数据变化更新视图,视图变化更新数据。vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是vue的精髓之处了。
原文链接4 原文链接1
- 第一步,“数据劫持”:vue 2.x 用 Object.defineProperty() 方法来实现数据劫持,为每个属性分配一个订阅者集合的管理列表 watcherList ;vue 3.x 用 ES6 的 Proxy 构造函数 来实现数据劫持。通过 DefineProperty 劫持各个数据的 setter 和 getter ,并为每个数据添加一个订阅者列表 watcherList ,这个列表将会记录所有依赖这个数据的组件。响应式后的数据相当于消息的发布者。
- 第二步,“添加订阅者”:每个组件都对应一个 Watcher 订阅者,当组件渲染函数render执行时,此时会用到data里的响应式数据,触发getter方法,在getter方法中会将本组件的 Watcher 添加到所依赖的响应式数据的订阅者列表 watcherList 中。相当于完成了一次订阅,这个过程叫做“依赖收集”。添加方式包括:v-model 会添加一个订阅者,{{}} 也会,v-bind 也会,只要用到该属性的指令理论上都会。(见问题1、2)
- 第三步,“为 input 添加监听事件”:为 input 添加监听事件,事件中改变某响应式数据,当响应式数据发生变化时,会触发 setter(见问题3) ,setter 中调用该数据发布者的发布通知方法,通知订阅者数组 watcherList 循环调用各订阅者 Watcher 的 update() 方法更新视图, 触发组件重新渲染来更新视图(见问题4)。视图层相当于消息的订阅者。
双向绑定的实现:数据劫持 + 观察者模式(发布者-订阅者模式)。
观察者模式又叫发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
发布-订阅模式的角色有两类:发布者和订阅者
写一个发布-订阅模式:
Vue的双向数据绑定