MVVM 视图模型双向数据绑定之核心原理
1 概述
2 MVVM,Model-View-ViewModel
3 双向数据绑定
4 监听 DOM 改变
5 监听模型数据变化,数据劫持
6 观察者模式,Observer
1 概述
JS 几个流行的框架 Vuejs、Ember.js、AngularJS 都使用 MVVM 模式,该模式叫做视图模型双向数据绑定,以达到数据和视图快速同步的目的。本文就对其中涉及的原理部分加以说明(后续还有一篇模拟 实现)。主要体现就是表单元素值变,JS变量值改变,若页面上有输出,输出值也改变,典型的代码如下,vuejs.org 上提供的例子:
1// HTML 2<div id="app"> 3 <p>{{ message }}</p> 4 <input v-model="message"> 5</div> 6 7// JS 8var app6 = new Vue({ 9 el: '#app', 10 data: { 11 message: 'Hello Vue!' 12 } 13})
效果:
文内容包括但不限于:
- MVVM 数据双向绑定
- DOM 事件监听
- 数据劫持
- 观察者模式
先从什么是 MVVM 说起。
2 MVVM,Model-View-ViewModel
MVVM 拆开来是 Model-View-ViewModel,View,ViewModel,Model 三部分组成,它是一种前端开发的架构模式。
- View :代表的是视图,模版。它用来显示数据。
- Model :代表的是模型、数据,可以在 Model 层中定义数据修改和操作的业务逻辑。
- ViewModel :连接 Model 和 View。
如图所示:
在 MVVM 的架构下,View 层(DOM展示层)和 Model 层(数据对象层)并没有直接联系,而是通过 ViewModel 层进行交互。ViewModel 层通过双向数据绑定将 View 层和 Model 层连接了起来,使得 View 层和 Model 层的同步工作完全是自动的。
因此开发者只需关注业务逻辑,无需手动操作 DOM,复杂的数据状态维护交给 MVVM 统一来管理,称之为数据驱动的开发方法。
3 双向数据绑定
就是指数据的传递有两个方向:
- 方向1:从数据到视图,数据变化时,视图也变化。
- 方向2:从视图到数据,例如 input 框的内容变化时,JS 维护的数据也会变化,同时再次传递到视图上,视图也随之变化。
若要实现以上的数据传递,我们需要去监听数据变化和视图的变化,才能做出相应改变。
4 监听 DOM 改变
监听 DOM 视图的改变是为了更新模型。我们通过 DOM 事件就可以实现监听视图的改变,典型的 input 的 change、input 事件都可以完成监听,通过事件处理器,实现对应的模型的数据改变。
前面例子中的 input 元素的值的不断改变,就是 DOM 的改变,我们监听到之后,将模型变量 message 做同步更改!就是视图改变传递到了模型上。
那么为什么页面的展示也变了呢?就是下一个传递了。模型改变传递到视图上。数据的改变传递到视图上如何实现的呢?就是监听数据实现的。
5 监听模型数据变化,数据劫持
如何做到 message 模型变量的变化我们可以监听到呢?其实是利用的 JS 中对象属性修改的特殊 get、set 方法实现的,示例代码如下:
1var o = {}; // 创建一个新对象 2 3// 在对象中添加一个属性与存取描述符的示例 4var messageValue; 5Object.defineProperty(o, "message", { 6 get : function(){ 7 return messageValue; 8 }, 9 set : function(newValue){ 10 messageValue = newValue; 11 }, 12});
以上代码,我们就为对象 o 定义了属性 message。同时在 o.message 时会调用 message 对应的 get 方法,在 o.message = "some message" 时会调用 message 的 set 方法来实现。可以预见,我们可以在某个属性被设置修改时,执行我们的特定代码,我们正在监视某些属性的变化。有了这个监听,就可以实现当模型改变时,去更新对象的视图部分。
以上的代码,在设计上称之为:数据劫持。这个设计也是 MVVM 的核心原理之一。
关于 Object.defineProperty 大家可以参考:Object.defineProperty。除此之外 ES6 的 Proxy 也可以完成此项功能。据称 vue3 就会使用 Proxy 代替 defineProperty。
真正实现时,往往一个模型的变化,需要更新好多视图部分,因此设计时,通常会选用观察者模式。
6 观察者模式,Observer
观察者模式(也叫模型 Model - 视图 View 模式、源 Source - 收听者 Listener 模式或从属者模式)是设计模式的一种。在此模式中,一个目标对象管理所有依赖它的观察者对象,并且在本身的状态改变时发出通知。也就是本例中,模型就是目标对象,而所需要更新的各种视图DOM就是观察者。
本文不讨论观察者模式的问题,请移步:观察者模式及典型实现 一文。
以上就是 MVVM 和 其中涉及的关键原理概念。另一篇 MVVM 双向数据绑定之基础实现,通过代码展示如何实现 MVVM 模式。
如有帮助,请多多转载!