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 & DHTML 实例编程(教程)基础知识
Jun 02 Javascript
json 入门基础教程 推荐
Oct 31 Javascript
Jquery AJAX POST与GET之间的区别
Nov 14 Javascript
Jquery Ajax xmlhttp请求成功问题
Feb 04 Javascript
创建你的第一个AngularJS应用的方法
Jun 16 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
Aug 23 Javascript
jquery实现点击变换导航样式的方法
Aug 31 Javascript
使用jQuery判断Div是否在可视区域的方法 判断div是否可见
Feb 17 Javascript
深入理解JavaScript中的对象复制(Object Clone)
May 18 Javascript
jQuery之简单的表单验证实例
Jul 07 Javascript
前端自动化开发之Node.js的环境搭建教程
Apr 01 Javascript
webpack3之loader全解析
Oct 26 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示例详解Constructor Prototype Pattern 原型模式
2015/10/15 PHP
PHP var关键字相关原理及使用实例解析
2020/07/11 PHP
nodejs教程 安装express及配置app.js文件的详细步骤
2013/05/11 NodeJs
jQuery实现跟随鼠标运动图层效果的方法
2015/02/02 Javascript
jquery 删除节点 添加节点 找兄弟节点的简单实现
2016/12/07 Javascript
vuejs使用递归组件实现树形目录的方法
2017/09/30 Javascript
vue-devtools的安装步骤
2018/04/23 Javascript
详解如何在你的Vue项目配置vux
2018/06/04 Javascript
webpack手动配置React开发环境的步骤
2018/07/02 Javascript
详解Vue实战指南之依赖注入(provide/inject)
2018/11/13 Javascript
webpack优化的深入理解
2018/12/10 Javascript
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
JavaScript 自定义html元素鼠标右键菜单功能
2019/12/02 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
python使用PyFetion来发送短信的例子
2014/04/22 Python
基于python的Tkinter编写登陆注册界面
2017/06/30 Python
Python实现的大数据分析操作系统日志功能示例
2019/02/11 Python
利用Python+阿里云实现DDNS动态域名解析的方法
2019/04/01 Python
Python将string转换到float的实例方法
2019/07/29 Python
详解python安装matplotlib库三种失败情况
2020/07/28 Python
用python写爬虫简单吗
2020/07/28 Python
Numpy ndarray 多维数组对象的使用
2021/02/10 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
ECCO爱步官方旗舰店:丹麦鞋履品牌
2018/01/02 全球购物
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
2019年Java 最常见的 面试题
2016/10/19 面试题
编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的
2015/07/23 面试题
Java servlet面试题
2012/03/04 面试题
JS原生实现轮播图的几种方法
2021/03/23 Javascript
大四自我鉴定范文
2013/10/06 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
经营理念口号
2014/06/21 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
博士生导师推荐信
2014/07/08 职场文书
企业财务管理制度范本
2015/08/04 职场文书
2016年公司中秋节致辞
2015/11/26 职场文书