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中通过闭包解决只能取得包含函数中任何变量最后一个值的问题
Aug 12 Javascript
使用原生javascript创建通用表单验证——更锋利的使用dom对象
Sep 13 Javascript
服务器端的JavaScript脚本 Node.js 使用入门
Mar 07 Javascript
javascript的propertyIsEnumerable()方法使用介绍
Apr 09 Javascript
js实现网页标题栏闪烁提示效果实例分析
Nov 20 Javascript
jquery插件autocomplete用法示例
Jul 01 Javascript
利用Node.js编写跨平台的spawn语句详解
Feb 12 Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 Javascript
vue地址栏直接输入路由无效问题的解决
Nov 15 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
Mar 13 Javascript
详解使用uni-app开发微信小程序之登录模块
May 09 Javascript
原生JavaScript实现留言板
Jan 10 Javascript
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反向代理类代码
2014/08/15 PHP
php验证手机号码
2015/11/11 PHP
深入浅析php json 格式控制
2015/12/24 PHP
php打乱数组二维数组多维数组的简单实例
2016/06/17 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
2016/10/11 PHP
PHP实现重载的常用方法实例详解
2017/10/18 PHP
破除网页鼠标右键被禁用的绝招大全
2006/12/27 Javascript
JS 添加网页桌面快捷方式的代码详细整理
2012/12/27 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
Javascript中string转date示例代码
2013/11/01 Javascript
js中prototype用法详细介绍
2013/11/14 Javascript
引用 js在IE与FF之间的区别详细解析
2013/11/20 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
禁止按回车键提交表单的方法
2015/06/11 Javascript
js实现带圆角的两级导航菜单效果代码
2015/08/24 Javascript
详谈javascript异步编程
2016/02/21 Javascript
js实现常用排序算法
2016/08/09 Javascript
微信小程序 基础组件与导航组件详细介绍
2017/02/21 Javascript
jQuery Ajax自定义分页组件(jquery.loehpagerv1.0)实例详解
2017/05/01 jQuery
移动设备手势事件库Touch.js使用详解
2017/08/18 Javascript
vue2.0 实现导航守卫的具体用法(路由守卫)
2018/05/17 Javascript
Vue.Draggable拖拽功能的配置使用方法
2020/07/29 Javascript
[15:28]DOTA2 HEROS教学视频教你分分钟做大人-剧毒术士
2014/06/13 DOTA
[52:44]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第一场 6.3
2018/06/04 DOTA
python实现爬虫统计学校BBS男女比例之数据处理(三)
2015/12/31 Python
python dataframe 输出结果整行显示的方法
2018/06/14 Python
pyttsx3实现中文文字转语音的方法
2018/12/24 Python
python截取两个单词之间的内容方法
2018/12/25 Python
Python基于Twilio及腾讯云实现国际国内短信接口
2020/06/18 Python
Python常用断言函数实例汇总
2020/11/30 Python
传统HTML页面实现模块化加载的方法
2018/10/15 HTML / CSS
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
好家长事迹材料
2014/01/23 职场文书
接待员岗位责任制
2014/02/10 职场文书
合作协议书怎么写
2014/04/18 职场文书
派出所所长先进事迹
2014/05/19 职场文书