Vue双向数据绑定(MVVM)的原理

(编辑:jimmy 日期: 2024/12/24 浏览:2)

MVVM

  MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。

Vue双向数据绑定(MVVM)的原理

  Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

数据劫持

  vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

Object.defineProperty()

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

  Object.defineProperty(obj, prop, descriptor)

参数:

  •   obj--要在其上定义属性的对象。
  •   prop--要定义或修改的属性的名称。
  •   descriptor--将被定义或修改的属性描述符。

返回值:被传递给函数的对象。

MVVM 的数据双向绑定步骤

  1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者

  2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数

  3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
  4、MVVM入口函数,整合以上三者。

  流程如下所示:

Vue双向数据绑定(MVVM)的原理

实现Observer

  我们知道可以利用Obeject.defineProperty()来监听属性变动,那么将需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter。

  这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化。

实现Compile

  compile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图,如图所示:

Vue双向数据绑定(MVVM)的原理

实现Watcher

  Watcher订阅者作为Observer和Compile之间通信的桥梁,主要做的事情是:
  1、在自身实例化时往属性订阅器(dep)里面添加自己
  2、自身必须有一个update()方法
  3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。

实现MVVM

  MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁。

  达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

以上就是Vue双向数据绑定(MVVM)的原理的详细内容,更多关于Vue 双向数据绑定(MVVM)的资料请关注其它相关文章!

一句话新闻

一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?