专栏首页较真的前端探寻Vue数据双向绑定的底层原理

探寻Vue数据双向绑定的底层原理

小编我最近在研究Vue底层数据双向绑定的实现原理,目前还停留在比较肤浅的层面,先把最近的学习成果总结一下,分享给大家

什么是数据双向绑定

Vue增长趋势迅猛,很大程度上得益于他“数据双向绑定”的设计模式。所谓的双向绑定就是在数据与视图层相互映射,当数据发生变化时,相应的视图层会随之更新,相反的,如果视图层发生变化,那么相对应的数据也会随之发生变化。这也是一个典型的MVVM模型

MVVM模型

上图是一个MVVM模型的模块关系图。

图中的View为视图层,ViewModel代表逻辑控制层,Model代表数据层。

其中ViewModel作为视图层和数据层的代理,视图层变化会传递给ViewModel,数据层的变化也会传递给ViewModel,ViewModel再将变化通知给相应的数据层和视图层。

如何监测数据的变化

Vue官网关于如何检测到数据变化给出的解释是,Vue使用了Object.defineProperty方法在Vue模型初始化时,对于data进行遍历并重写他们的setter和getter方法,从而实现了数据变化的检测。由于Object.defineProperty是仅ES5才支持的方法,所以这也解释了为什么VUE对于低版本的浏览器不支持(仅支持IE8以上)。

简单回顾一下setter和getter:Object的原生方法defineProperty可以来定义Object中的一些属性,包括enumerable(是否可以被枚举)、writable(是否可写)、get(获取属性值时调用的方法)、set(设定属性值调用的方法)。

可以看MDN中给出的例子来进一步理解setter和getter的运行原理。

有了getter/setter方法,Vue就可以对于data中的数据进行监测了(Observe)。知道了这一点,你就会明白为什么Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。

如何检测视图层的变化

视图层的变化很容易监测到,可以直接利用浏览器的事件触发机制。Vue实现了一个指令编译器Compiler来对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。

如何实现双向绑定

通过上面的讲解,我们已经知道Vue是如何检测到数据层和视图层的变化了,那么Vue是如何将二者的变化进行相互响应式的更新呢?

Vue自身实现一个Watcher,作为连接Observer和Compile的桥梁。而数据层的Observe和视图层的Compile都是基于观察者模式实现的,再加上Watcher这个中间桥梁,Vue实例能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

总结

Vue的数据双向绑定是基于Object.defineProperty方法的“数据劫持”和观察者模式而开发的。本篇并没有深入研究Observe、Compiler、Watcher的底层代码,只是从软件分层和核心思路来讨论Vue的实现原理,事实上Vue还有很多很多高深的算法和内部优化逻辑,如异步更新队列和Virtual DOM等等。今后有机会再与大家分享这些内容。

本文分享自微信公众号 - 较真的前端(gh_7af41a2be77e),作者:英俊潇洒你冲哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 尤雨溪分享Vue3最新进展▶️

    第二届VueConf 于2018年11月24在杭州举行。Vue的作者——尤雨溪远程参与并做了大会的第一个演讲。以下内容节选至尤雨溪的演讲视频。

    用户1687375
  • React 学习路线图 2018版

    这个 React 学习路线的思维导图来源自 Adam Gołąb 的 react-developer-roadmap 。截止至本文发布时,原仓库已经有了中文版,...

    用户1687375
  • 十几行代码就可以让你的微信小程序挂掉

    mpvue是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue修改了 Vue.js 的 runtime 和 compiler...

    用户1687375
  • UIView不可不知的秘密

    Dwyane
  • MySQL视图操作

    视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。 通过视图,可以展现基表的部分数据;视图数据来自...

    A梦多啦A
  • MySQL视图的创建与使用

    视图是MySQL的一种虚拟表,实际的表我们可以看到每一行的数据,而视图是另一种形式的表,他可以将任何的查询结果变成一种虚拟的表方便下一次进行查询。

    大猫的Java笔记
  • MySQL视图示例

    视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。 通过视图,可以展现基表的部分数据;视图数据来自...

    A梦多啦A
  • SwiftUI:使用 @EnvironmentObject 从环境中读取自定义值

    SwiftUI的环境使我们可以使用来自外部的值,这对于读取Core Data上下文或视图的展示模式等很有用。但是我们也可以将自定义对象发送到环境中,并在以后将它...

    韦弦zhy
  • MySQL引擎和视图的点

    存储引擎Storage Engine:MySQL中的数据、索引以及其他对象是如何存储的,是一套文件系统的实现。

    孙玄@奈学教育
  • jenkins 视图使用

     job建立的特别多的时候,我们可能不太容易找到自己的某个job,这时,我们就可以在Jenkins中建立视图。job的视图类似于我们电脑上的文件夹。可以通过一些...

    py3study

扫码关注云+社区

领取腾讯云代金券