前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Angular(06)- 为什么数据变化,绑定的视图就会自动更新了?

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

作者头像
请叫我大苏
发布2019-07-18 15:33:11
1.6K0
发布2019-07-18 15:33:11
举报
文章被收录于专栏:AndroidTvAndroidTv

这里提一点,前端三大框架(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) 这样的操作。

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档