这里提一点,前端三大框架(Angular,React,Vue)的数据驱动来更新视图的原理,即 MVVM 的实现。
为什么数据发生变化,绑定的视图就会刷新了呢?

以下是我的个人理解,仅供参考:

在还是 jQuery 的时代,当在 js 中改变了某个变量的数据,而这个变量是需要在 Html 中显示出来的。那么,这个时候,我们的做法也就是通过 DOM 先获取到显示该变量的视图元素,然后借助 DOM API 来更新这个视图元素,是吧。这是原始的方式。

那么,不管三大框架都做了些什么,MVVM 的实现原理是什么,它们最终其实也都还是要通过操纵 DOM API 来更新视图元素,与原始方式的区别就是,这部分操纵 DOM 的工作,由框架来负责,我们无需关心了,只需要关心数据的变化工作即可。

好处就是,我们可以更关注于业务逻辑的编程,而无须再去为如何操纵 DOM 树而烦恼。

那么,既然框架要来帮我们处理这部分工作,它们实现的关键点就在于,如何知道,我们对数据进行了更新?

什么意思?也就是说,这部分工作由我们自己来做时,我们是能够明确的知道什么时候该去操纵 DOM 树了,不就是我们对数据进行更新的时刻吗。但,框架并不知道我们什么时刻会对数据进行更新。

所以,回想一下,你在使用三大框架时,是不是每个框架基本都有一些注意事项,或者说它的规定?

比如说:

react 要求修改 state 局部变量时,得通过 this.setState(...)
vue 要求得声明在 data 中的变量,当它变化时才会被追踪到,以更新视图

为什么这些框架会有这些要求,或者说这些规定?
因为它需要知道我们到底什么时刻会去对数据进行更新啊。

对于 react 来说,当我们需要更新变量的数据值时,都通过调用它的方法,那么,它自然就知道我们什么时候更新了数据了。

对于 vue 来说,虽然我们更新数据时是直接对变量进行赋值操作,但实际上,声明在 data 中的这些变量,都会被转换成存取器属性,也就是 set 和 get。那么,当我们直接对变量的赋值操作,其实会去执行 set 的内部逻辑,而 vue 只需要在这里就可以获取我们更新数据的时机了。

那么,对于 Angular 呢?好像使用 Angular 过程中,并没有需要遵循什么规定。

这是因为,Angular 的实现原理并不类似于 react 和 vue。

react 和 vue 的原理类似于主动通知的模式,也就是,当我发生变化了,那我就通知你一下,你就需要去做些更新处理了。

Angular 的原理,类似于被动轮询的模式。也就是,你不知道我什么时候会变化,那么你就在我有可能会变化的情况下,不断的读取我的值,比对一下,看看有没有发生变化。

验证 Angular 的这种原理的猜测很简单,你在页面上某个元素绑定个方法,方法内打个日志,然后你滑动下页面试试看,看看日志是不是一直在输出。

总结一下:
三大框架实现的原理其实有所差异
react 是通过调用 setState() 方式来告知视图刷新;
vue 是通过将声明在 data 中的数据属性转换为存取器数据(set 和 get)的方式,来监听数据变化的时机;
angular 则是在会触发视图变化的情况下,主动去检测绑定的数据源,比对下是否有发生变化来判断是否需要刷新视图。

当然,以上的理解仅仅是很浅的层面,只是理清了三大框架是如何知道我们数据更新的时机这个问题。

对于三大框架来说,他们的视图刷新并非是这么简单的实现。比如说:

对于 vue,当它监听到某个数据源发生变化了,但它并不会立马去刷新视图,而是将相关的信息先记录起来,等待一个固定频率的下个帧信号,在这期间发生变化的数据源都会被记录起来。直到信号来的时候,再一起去处理这次的视图刷新。

这也是为什么一些 vue 的书中或者项目中,会有要求说某些代码需要放在下一个 tick 中去执行,因为数据源刚发生变化时,页面不一定就更新了。

原理跟 Android 的屏幕刷新机制很像,就都是以一个固定频率来刷新页面,在每个帧信号之间,只是收集发生变化的视图,或者说,只更新虚拟 DOM,并不会去更新真实的页面。直到帧信号到的时候,再一次性的批处理地刷新页面。

对于 Angular 来说,虽然它是不断轮询的方式来检测数据源是否发生变化,但并不意味着时时刻刻都在轮询检测,而只在一些有可能导致视图更新的场景下才会去检测。比如说,滑动页面,比如说 settimeout 事件。

这也是为什么在 Angular 项目中,经常会看到一些 settimeout(..., 0) 这样的操作。

以上,个人的理解,如有错误,欢迎指点一下。

Angular(06)- 为什么数据变化,绑定的视图就会自动更新了?的更多相关文章

  1. WPF非轮询方式更新数据库变化SqlDependency(数据库修改前台自动更新)

    上一章节我们讲到wpf的柱状图组件,它包含了非轮询方式更新数据库变化SqlDependency的内容,但是没有详细解释,现在给大家一个比较简单的例子来说明这部分内容. 上一章节: WPF柱状图(支持数 ...

  2. mssql sqlserver 表增加列后,视图不会自动更新相关列的两种解决方法分享

    摘要: 今天对物理数据表,进行增加列操作后,程序一直显示无法找到相应列,通过仔细比对发现,视图中无相应列更新,下文将具体的解决方法分享如下: 例: create view vw_test as sel ...

  3. sqlserver 问题来了,视图不会自动更新,如果是用*创建的

    奇葩问题一个 create view时候用的select * 关联了几个表创建的. 后修改select *  的表,结果悲剧了. select * from 视图得到的结果绝对让你想哭.不报错,不提示 ...

  4. GridView中给DropDownList动态绑定数据,及选择列表值后自动更新数据库

    protected void sgvFile1_RowDataBound(object sender, GridViewRowEventArgs e) { DropDownList ddlAM = ( ...

  5. AngularJS学习笔记(三)数据双向绑定

    双向绑定 双向绑定是AngularJS最实用的功能,它节省了大量的代码,使我们专注于数据和视图,不用浪费大量的代码在Dom监听.数据同步上,关于双向更新,可看下图: 下面,我们通过代码来实现.先不要纠 ...

  6. 前端笔记之微信小程序(二){{}}插值和MVVM模式&数据双向绑定&指令&API

    一.双花括号{{}}插值和MVVM模式 1.1 体会{{}}插值 index.wxml的标签不是html的那些标签,这里的view就是div. {{}}这样的插值写法,叫做mustache语法.mus ...

  7. Vue.js学习 Item4 -- 数据双向绑定

    Vue.js 的模板是基于 DOM 实现的.这意味着所有的 Vue.js 模板都是可解析的有效的 HTML,且通过一些特殊的特性做了增强.Vue 模板因而从根本上不同于基于字符串的模板,请记住这点. ...

  8. angular.js 中同步视图和模型数据双向绑定,$watch $digest $apply 机制

    Angular.js 中的特性,双向绑定. 让视图的改变直接反应到数据中,数据的改变又实时的通知到视图,如何做到的? 这要归功于 scope 下面3个重要的方法: $watch $digest $ap ...

  9. Angular数据双向绑定

    Angular数据双向绑定 AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.Angul ...

随机推荐

  1. 转:Eclipse中创建Maven版的Web工程(详解)

    一.搭建步骤 ♦首先创建一个Maven的Project,如下图: ♦点击Next,勾选 Create a simple project ♦点击Next,注意Packing要选择war,因为我们创建的是 ...

  2. Asp.net Core 3.0 Identity 使用smtp账户确认和密码恢复

    当新建一个core项目后,使用identity基架后,确认邮件出现了错误,并不能正常使用. 建立文档在这里 https://docs.microsoft.com/zh-cn/aspnet/core/s ...

  3. jQuery中detach&&remove&&empty三种方法的区别

    jQuery中empty&&remove&&detach三种方法的区别 empty():移除指定元素内部的所有内容,但不包括它本身 remove():移除指定元素内部的 ...

  4. eclipse maven 项目导出为 jar 包

    一个 maven 项目有很多依赖,所以最后打出的 jar 一般会很多,且比较大,打成 jar 包的步骤 (注意pom.xml文件中打包类型不能是war包): 1. 把 pom.xml 中依赖的库打成 ...

  5. 产品vs程序员:你知道www是怎么来的吗?

    精彩回顾: 我是一个explorer的线程 我是一个杀毒软件线程 我是一个IE浏览器线程 比特宇宙-TCP/IP的诞生 Unix.Linux.Windows三大帝国集团发表<关于比特宇宙推进经贸 ...

  6. IOS UISwitch 控件

    转自:http://my.oschina.net/wolx/blog/396680 一 UISwitch 简介 二 UISwitch 创建 三设置选中状态 四 添加监听 五 测试代码 5.1 代码 5 ...

  7. Codeforces Round #595 (Div. 3) D2Too Many Segments,线段树

    题意:给n个线段,每个线段会覆盖一些点,求删最少的线段,使得每个点覆盖的线段不超过k条. 思路:按右端点排序,之后依次加入每个线段,查询线段覆盖区间内的每个点,覆盖的最大线段数量,如果不超过k,那就可 ...

  8. 第5节:Java基础 - 必知必会(下)

    第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...

  9. VIP 视频开发板 上位机 测试软件 下载地址,玩转各自分辨率(V201抢先版)

    本上位机最高测试帧率 133fps 目前支持分辨率:更多分辨率支持,敬请期待或给我留言VGA:640*4801.3M:1280*10242M:1600*1200786p:1024*768 格式兼容:1 ...

  10. python基础入门while循环 格式化 编码初识

    一.while循环 1.格式 while+空格+条件+英文冒号: ​ 缩进+结果(循环体) ​ #若条件为真则一直执行,条件为假则不执行 while True: print('痒') print('. ...