这里提一点,前端三大框架(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. 【华为云分享】MongoDB-系统时钟跳变引发的风波

    目录 背景 一. 对 oplog 的影响 oplog 原理 二.主备倒换 小结 声明:本文同步发表于 MongoDB 中文社区,传送门:http://www.mongoing.com/archives ...

  2. python获取bing地图发布自己的TMS服务(一)下载瓦片

    部分结果 bing地图瓦片使用QuadKey作为命名方式. QuadKey简介 如何计算quadkey 在给定level下,把行号tileY和列号tileX转换为2进制,然后行列交叉存储,再转换为4进 ...

  3. HDU1517 Multiply Game

    Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 t ...

  4. 将项目部署到github的方法

    GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线,除了Git代码仓库托管及基本的 We ...

  5. 模电&数电知识整理(不定期更新)

    模电总复习之爱课堂题目概念整理 Chapter 1 1) 设室温情况下某二极管的反偏电压绝对值为1V,则当其反偏电压值减少100mV时,反向电流的变化是基本不发生变化. 2) 二极管发生击穿后,在击穿 ...

  6. SpringBoot系列之集成Mybatis教程

    SpringBoot系列之集成Mybatis教程 环境准备:IDEA + maven 本博客通过例子的方式,介绍Springboot集成Mybatis的两种方法,一种是通过注解实现,一种是通过xml的 ...

  7. 使用ExcelPackage进行Excel报表

    Nuget包名为 epplus.core 命名空间OfficeOpenXml string localFileName = path + Path.DirectorySeparatorChar + f ...

  8. 常见的RuntimeException报错原因

    对于RuntimeException 做java开发的朋友想必不会陌生,可以用于事物的回滚操作.异常类型也有很多种,写这篇文章主要是为了总结自己开发中遇到的一些异常类型 以便帮助大家遇到相应的报错找不 ...

  9. VMware虚拟机安装Linux(CentOS)系统

    vmware workstation 虚拟机官方下载路径:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-eval ...

  10. VS Code 成主宰、Vue 备受热捧!2019 前端开发趋势必读

    前端在生产和开发中占据着越来越重要的地位,PC 端.手机端.桌面端.智能手表端等等设备都离不开前端的身影.本文将围绕框架.编程语言.工具.React.Vue 等方面,全面回顾 2019 年前端与 We ...