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


Posted in Javascript onOctober 03, 2020

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)的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
javascript prototype 原型链
Mar 12 Javascript
Android中的jQuery:AQuery简介
May 06 Javascript
Node.js中使用计时器定时执行函数详解
Aug 15 Javascript
基于jQuery实现复选框是否选中进行答题提示
Dec 10 Javascript
JS实现n秒后自动跳转的两种方法
Nov 30 Javascript
针对后台列表table拖拽比较实用的jquery拖动排序
Oct 10 Javascript
javascript显示系统当前时间代码
Dec 29 Javascript
Vue 组件间的样式冲突污染
Aug 31 Javascript
react-native DatePicker日期选择组件的实现代码
Sep 12 Javascript
微信小程序倒计时功能实现代码
Nov 09 Javascript
ES6基础之默认参数值
Feb 21 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
Chrome插件开发系列一:弹窗终结者开发实战
Oct 02 #Javascript
js通过canvas生成图片缩略图
Oct 02 #Javascript
JS检测浏览器开发者工具是否打开的方法详解
Oct 02 #Javascript
JavaScript检测是否开启了控制台(F12调试工具)
Oct 02 #Javascript
js屏蔽F12审查元素,禁止修改页面代码等实现代码
Oct 02 #Javascript
js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
Oct 01 #Javascript
JS禁用右键、禁用Ctrl+u、禁用Ctrl+s、禁用F12的实现代码
Dec 01 #Javascript
You might like
PHP中的日期处理方法集锦
2007/01/02 PHP
php 获取百度的热词数据的代码
2012/02/18 PHP
php入门之连接mysql数据库的一个类
2012/04/21 PHP
深入php socket的讲解与实例分析
2013/06/13 PHP
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
2014/08/25 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
2016/04/11 PHP
如何离线执行php任务
2017/02/21 PHP
jquery 事件对象属性小结
2010/04/27 Javascript
ASP.NET jQuery 实例1(在TextBox里面创建一个默认提示)
2012/01/13 Javascript
js判断上传文件类型判断FileUpload文件类型代码
2014/05/20 Javascript
纯javascript模仿微信打飞机小游戏
2015/08/20 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
浅谈JavaScript的全局变量与局部变量
2016/06/10 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
jQuery表单对象属性过滤选择器实例详解
2016/09/13 Javascript
浅谈js对象的创建和对6种继承模式的理解和遐想
2016/10/16 Javascript
easyui tree带checkbox实现单选的简单实例
2016/11/07 Javascript
Javascript循环删除数组中元素的几种方法示例
2017/05/18 Javascript
angularjs中$http异步上传Excel文件方法
2018/02/23 Javascript
JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍
2018/03/01 Javascript
小程序云开发如何实现图片上传及发表文字
2019/05/17 Javascript
解决Vue项目打包后打开index.html页面显示空白以及图片路径错误的问题
2019/10/25 Javascript
python文件和目录操作方法大全(含实例)
2014/03/12 Python
利用Python开发实现简单的记事本
2016/11/15 Python
对python实现二维函数高次拟合的示例详解
2018/12/29 Python
numpy中的ndarray方法和属性详解
2019/05/27 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
美国最大的网络男装服装品牌:Bonobos
2017/05/25 全球购物
世界上最受欢迎的钓鱼诱饵:Rapala
2019/05/02 全球购物
Nip + Fab官网:英国美容品牌
2019/08/26 全球购物
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
建材投资建议书
2014/05/16 职场文书
少先队活动总结
2014/08/29 职场文书
人事代理委托书
2014/09/27 职场文书
2014年管理人员工作总结
2014/12/01 职场文书
优秀党员事迹材料
2014/12/18 职场文书