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 06 Javascript
运用jQuery定时器的原理实现banner图片切换
Oct 22 Javascript
Angular实现form自动布局
Jan 28 Javascript
Vue.js每天必学之过渡与动画
Sep 06 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
Sep 20 Javascript
JavaScript队列的应用实例详解【经典数据结构】
Apr 12 Javascript
js如何获取网页所有图片
May 12 Javascript
vue-router实现tab标签页(单页面)详解
Oct 17 Javascript
JavaScript中的一些隐式转换和总结(推荐)
Dec 22 Javascript
vue.js,ajax渲染页面的实例
Feb 11 Javascript
使用vue-router设置每个页面的title方法
Feb 11 Javascript
Vue2.0 ES6语法降级ES5的操作
Oct 30 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使用glob函数快速查询指定目录文件的方法
2014/11/15 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
PHP加密解密函数详解
2015/10/28 PHP
Yii2实现同时搜索多个字段的方法
2016/08/10 PHP
PHP代码重构方法漫谈
2018/04/17 PHP
PHP strripos函数用法总结
2019/02/11 PHP
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
jquery结合CSS使用validate实现漂亮的验证
2015/01/29 Javascript
纯javascript移动优先的幻灯片效果
2015/11/02 Javascript
JavaScript实现短信倒计时60s
2017/10/09 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
2018/09/25 Javascript
JavaScript多种图形实现代码实例
2020/06/28 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
如何编写一个 Webpack Loader的实现
2020/10/18 Javascript
Vue时间轴 vue-light-timeline的用法说明
2020/10/29 Javascript
微信小程序实现星星评分效果
2020/11/01 Javascript
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
[48:21]Mski vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
打开电脑上的QQ的python代码
2013/02/10 Python
浅谈python抛出异常、自定义异常, 传递异常
2016/06/20 Python
python高级特性和高阶函数及使用详解
2018/10/17 Python
Python中xml和json格式相互转换操作示例
2018/12/05 Python
Django框架视图层URL映射与反向解析实例分析
2019/07/29 Python
pyqt5 QScrollArea设置在自定义侧(任何位置)
2019/09/25 Python
PyTorch: Softmax多分类实战操作
2020/07/07 Python
墨西哥皇宫度假村预订:Palace Resorts
2018/06/16 全球购物
民生工程实施方案
2014/03/22 职场文书
企业年会主持词
2014/03/27 职场文书
初中班主任寄语
2014/04/04 职场文书
财务管理专业毕业生求职信
2014/06/02 职场文书
党员自我评议个人对照检查材料
2014/09/16 职场文书
群众路线剖析材料怎么写
2014/10/09 职场文书
会计工作能力自我评价
2015/03/05 职场文书
倡议书范文大全
2015/04/28 职场文书
《索溪峪的野》教学反思
2016/02/19 职场文书
MySQL8.0的WITH查询详情
2021/08/30 MySQL