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 实现各种跨域的方法
May 08 Javascript
js报$ is not a function 的问题的解决方法
Jan 20 Javascript
javascript中Date()函数在各浏览器中的显示效果
Jun 18 Javascript
在web中js实现类似excel的表格控件
Sep 01 Javascript
bootstrap栅格系统示例代码分享
May 22 Javascript
requirejs + vue 项目搭建详解
Jun 16 Javascript
详解使用路由延迟加载 Angular 模块
Oct 12 Javascript
Smartour 让网页导览变得更简单(推荐)
Jul 19 Javascript
Nuxt配置Element-UI按需引入的操作方法
Jul 06 Javascript
封装 axios+promise通用请求函数操作
Aug 11 Javascript
为什么推荐使用JSX开发Vue3
Dec 28 Vue.js
一起来了解一下JavaScript的预编译(小结)
Mar 01 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 和 XML: 使用expat函数(三)
2006/10/09 PHP
PHP 中执行排序与 MySQL 中排序
2009/04/21 PHP
php代码书写习惯优化小结
2013/06/20 PHP
php通过session防url攻击方法
2014/12/10 PHP
详解PHP中instanceof关键字及instanceof关键字有什么作用
2015/11/05 PHP
PHP7+Nginx的配置与安装教程详解
2016/05/10 PHP
Yii遍历行下每列数据的方法
2016/10/17 PHP
javascript 学习笔记(六)浏览器类型及版本信息检测代码
2011/04/08 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
html的DOM中Event对象onblur事件用法实例
2015/01/21 Javascript
再JavaScript的jQuery库中编写动画效果的指南
2015/08/13 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
Jquery通过ajax请求NodeJS返回json数据实例
2016/11/08 NodeJs
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
2017/02/08 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
详解vue前后台数据交互vue-resource文档
2017/07/19 Javascript
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
JavaScript动态检测密码强度原理及实现方法详解
2019/06/11 Javascript
python获得图片base64编码示例
2014/01/16 Python
Python中的生成器和yield详细介绍
2015/01/09 Python
基于Python log 的正确打开方式
2018/04/28 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
Python字符串的一些操作方法总结
2019/06/10 Python
python requests指定出口ip的例子
2019/07/25 Python
python dict乱码如何解决
2020/06/07 Python
lookfantastic荷兰:在线购买奢华护肤、护发和化妆品
2018/11/27 全球购物
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
《木笛》教学反思
2014/03/01 职场文书
大课间体育活动方案
2014/03/12 职场文书
环保倡议书400字
2014/05/15 职场文书
庭外和解协议书
2016/03/23 职场文书
Vue vee-validate插件的简单使用
2021/06/22 Vue.js
MySQL慢查询优化解决问题
2022/03/17 MySQL
详解Spring Security中的HttpBasic登录验证模式
2022/03/17 Java/Android
德劲DE1105机评
2022/04/05 无线电