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 相关文章推荐
jquery实现的网页自动播放声音
Apr 30 Javascript
JavaScript学习笔记之JS对象
Jan 22 Javascript
JavaScript 模块化编程(笔记)
Apr 08 Javascript
jquery+CSS3模拟Path2.0动画菜单效果代码
Aug 31 Javascript
Position属性之relative用法
Dec 14 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
Dec 16 Javascript
js 判断一组日期是否是连续的简单实例
Jul 11 Javascript
AngularJS使用ocLazyLoad实现js延迟加载
Jul 05 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
Oct 11 Javascript
微信小程序实现点击文字页面跳转功能【附源码下载】
Dec 12 Javascript
JavaScript中将值转换为字符串的五种方法总结
Jun 06 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
Nov 09 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
玩转虚拟域名◎+ .
2006/10/09 PHP
PHP删除数组中指定下标的元素方法
2018/02/03 PHP
PHP安装BCMath扩展的方法
2019/02/13 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
FCK调用方法..
2006/12/21 Javascript
详细讲解JS节点知识
2010/01/31 Javascript
Webkit的跨域安全问题说明
2011/09/13 Javascript
JavaScript实现页面实时显示当前时间的简单实例
2013/07/20 Javascript
JS禁用浏览器退格键实现思路及代码
2013/10/29 Javascript
jquery获得同源iframe内body下标签的值的方法
2014/09/25 Javascript
Javascript 判断两个IP是否在同一网段实例代码
2016/11/28 Javascript
js实现添加删除表格(两种方法)
2017/04/27 Javascript
微信小程序实现image组件图片自适应宽度比例显示的方法
2018/01/16 Javascript
浅析Vue实例以及生命周期
2018/08/14 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
2018/09/05 Javascript
微信小程序wepy框架学习和使用心得详解
2019/05/24 Javascript
jQuery 筛选器简单操作示例
2019/10/02 jQuery
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
[01:32]DOTA2次级联赛——首支职业女子战队选拔赛全记录
2014/10/23 DOTA
python进阶教程之模块(module)介绍
2014/08/30 Python
Python实现将n个点均匀地分布在球面上的方法
2015/03/12 Python
用Python实现一个简单的能够发送带附件的邮件程序的教程
2015/04/08 Python
使用python语言,比较两个字符串是否相同的实例
2018/06/29 Python
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
pytorch之inception_v3的实现案例
2020/01/06 Python
Python填充任意颜色,不同算法时间差异分析说明
2020/05/16 Python
Django如何使用redis作为缓存
2020/05/21 Python
html5中 media(播放器)的api使用指南
2014/12/26 HTML / CSS
Nice Kicks网上商店:ShopNiceKicks.com
2018/12/25 全球购物
香港艺人陈冠希创办的潮流品牌:JUICESTORE
2021/03/04 全球购物
公积金转移接收函
2014/01/11 职场文书
迟到早退检讨书
2014/02/10 职场文书
机关作风建设自查报告
2014/10/22 职场文书
2015年信贷员工作总结
2015/04/28 职场文书
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
2022/02/12 Servers