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实例教程(19) 使用HoTMetal(5)
Dec 23 Javascript
JavaScript 学习笔记(五)
Dec 31 Javascript
详解Javascript动态操作CSS
Dec 08 Javascript
跟我学习javascript的call(),apply(),bind()与回调
Nov 16 Javascript
JS组件Form表单验证神器BootstrapValidator
Jan 26 Javascript
浅谈ECMAScript6新特性之let、const
Aug 02 Javascript
微信小程序url与token设置详解
Sep 26 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
Nov 17 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
Aug 01 Javascript
JavaScript设计模式之观察者模式实例详解
Jan 16 Javascript
多页vue应用的单页面打包方法(内含打包模式的应用)
Jun 11 Javascript
vue实现Toast组件轻提示
Apr 10 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 柱状图实现代码
2009/12/04 PHP
PHP中根据IP地址判断城市实现城市切换或跳转代码
2012/09/04 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
全新Mac配置PHP开发环境教程
2016/02/03 PHP
PHP检测用户是否关闭浏览器的方法
2016/02/14 PHP
PHP使用PDO实现mysql防注入功能详解
2019/12/20 PHP
JQuery Tips(3) 关于$()包装集内元素的改变
2009/12/14 Javascript
JavaScript 学习笔记(十四) 正则表达式
2010/01/22 Javascript
过虑特殊字符输入的js代码
2010/08/05 Javascript
js禁止小键盘输入数字功能代码
2011/08/01 Javascript
jquery 跳到顶部和底部动画2句代码简单实现
2013/07/18 Javascript
获取select元素被选中的文本内容的js代码
2014/01/29 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
2015/09/16 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
2016/11/01 Javascript
js使用Replace结合正则替换重复出现的字符串功能示例
2016/12/27 Javascript
微信小程序movable view移动图片和双指缩放实例代码
2017/08/08 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
微信小程序版翻牌小游戏
2018/01/26 Javascript
Vue.js的动态组件模板的实现
2018/11/26 Javascript
vue+SSM实现验证码功能
2018/12/07 Javascript
vue视图不更新情况详解
2019/05/16 Javascript
[03:59]第二届DOTA2亚洲邀请赛选手传记-VGJ.rOtk
2017/04/03 DOTA
10款最好的Web开发的 Python 框架
2015/03/18 Python
实践Python的爬虫框架Scrapy来抓取豆瓣电影TOP250
2016/01/20 Python
python学生信息管理系统
2018/03/13 Python
pycharm恢复默认设置或者是替换pycharm的解释器实例
2018/10/29 Python
使用python获取邮箱邮件的设置方法
2019/09/20 Python
Python生成pdf目录书签的实例方法
2020/10/29 Python
三只松鼠官方旗舰店:全网坚果销售第1
2017/11/25 全球购物
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
建筑总经理岗位职责
2014/02/02 职场文书
python中pandas对多列进行分组统计的实现
2021/06/18 Python
python not运算符的实例用法
2021/06/30 Python
Pytest中skip和skipif的具体使用方法
2021/06/30 Python