资讯专栏INFORMATION COLUMN

vue.js源码 - 剖析observer,dep,watch三者关系 如何具体的实现数据双向绑定

mo0n1andin / 1383人阅读

摘要:双向数据绑定的核心和基础是其内部真正参与数据双向绑定流程的主要有和基于和发布者订阅者模式,最终实现数据的双向绑定。在这里把双向数据绑定分为两个流程收集依赖流程依赖收集会经过以上流程,最终数组中存放列表,数组中存放列表。

Vue双向数据绑定的核心和基础api是Object.defineProperty,其内部真正参与数据双向绑定流程的主要有Obderver、Dep和Watcher,基于defineProperty和发布者订阅者模式,最终实现数据的双向绑定。那么Obderver、Dep和Watcher是如何具体配合工作的呢?下面就来理一理。

看此文章之前你需要对vue的双向数据绑定有一定的理解。若不了解可移步:vue.js源码解读系列 - 双向绑定具体如何初始化和工作

看到这里就当你对双向数据绑定已经有一定的理解:

提示:要看懂此篇文章你需要对vue的mvvm有一定的了解,并需要和专注的去理解,或者对照源码跟着走,不然就很难真的看懂。

在这里把双向数据绑定分为两个流程:

1、收集依赖流程:

observe -> 
walk -> 
defineReactive -> 
get -> 
dep.depend() -> 
watcher.addDep(new Dep()) -> 
watcher.newDeps.push(dep) -> 
dep.addSub(new Watcher()) -> 
dep.subs.push(watcher)

依赖收集会经过以上流程,最终watcher.newDeps数组中存放dep列表,dep.subs数组中存放watcher列表。

为什么要进行依赖收集?

new Vue({
    data(){
        return {
             name:"zane",
             sex:"男"
        }
    }
})

有上面这个data,实际上页面只使用到了name,并没有使用age,根据Object.defineProperty的转换,如果我们设置了this.sex="女",那么Vue也会去执行一遍虚拟DOM的比较,这样就无形的浪费了一些性能,因此才需要做依赖收集,界面用到了就收集,没有用到就不收集。

我们跟着流程走来理一遍源码:

直接进入Object.defineProperty的get方法:

考验你闭包能力的时候到了,这个dep对象就是一个闭包。记下来我们看看dep.depend()方法的实现。


先暂停一下,上面两处都用到了 Dep.target ,我也说了它就是一个Watcher实例化对象,你是不是很想搞懂它到底在哪里赋值的呢,不急请跟着我下面的代码看看。


搞懂了Dep.target等于一个Watche对象,现在继续回到之前的思路看watcher.addDep做了什么。


就这样依赖收集的流程就走完了,是否感觉很绕。

总结:依赖收集最终在 watcher.newDeps 中push了闭包中传过来的dep对象,在dep.subs中push了初始化Vue是简历的Watcher对象,这个对象的,this.getter = expOrFn,传过来的expOrFn是后期数据更新页面渲染的核心步骤,需要沉下心来好好去理理。

2、视图更新流程:

set -> 
dep.notify() -> 
subs[i].update() -> 
watcher.run() || queueWatcher(this) -> 
watcher.get() || watcher.cb -> 
watcher.getter() -> 
vm._update() -> 
vm.__patch__()

视图更新会经过以上流程,最终调用Vue的虚拟Dom diff过程实时更新界面视图





走到此处后面我就不去跟踪了,后面会调用vm.__patch__ 方法,进而执行虚拟DOM的diff过程实时的更新界面。

总结:
要很好的理解vue的数据双向绑定就要比较耐心,沉下心来慢慢理解,同时也需要对vue的源码有个大致的理解,不然你只会看的越来越烦躁越来越没有信心。

vue很好的利用了Object.defineProperty方法的 get和set方法,订阅者发布者的设计思路,巧妙的组织代码,值得我们很深入的去学习和理解,从而促使我们更好的去使用它。谢谢尤大的无私奉献,让我们提高了生产力,把更多的精力花到业务逻辑中去。

原文地址:https://github.com/wangweiang...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94214.html

相关文章

  • 剖析Vue实现原理 - 如何实现双向绑定mvvm(转载)

    摘要:接下来要看看这个订阅者的具体实现了实现订阅者作为和之间通信的桥梁,主要做的事情是在自身实例化时往属性订阅器里面添加自己自身必须有一个方法待属性变动通知时,能调用自身的方法,并触发中绑定的回调,则功成身退。 本文能帮你做什么?1、了解vue的双向数据绑定原理以及核心代码模块2、缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,...

    nemo 评论0 收藏0
  • 剖析Vue实现原理 - 如何实现双向绑定mvvm(转载)

    摘要:接下来要看看这个订阅者的具体实现了实现订阅者作为和之间通信的桥梁,主要做的事情是在自身实例化时往属性订阅器里面添加自己自身必须有一个方法待属性变动通知时,能调用自身的方法,并触发中绑定的回调,则功成身退。 本文能帮你做什么?1、了解vue的双向数据绑定原理以及核心代码模块2、缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,...

    DataPipeline 评论0 收藏0
  • Vue源码解析(2)-vue双向数据绑定原理

    摘要:与状态同步非常困难通过添加观察者监测变化,如和。应用中状态的属性会被监测,当它们发生变化时,只有依赖了发生变化属性的元素会被重新渲染。 现代 js 框架存在的根本原因 然而通常人们(自以为)使用框架是因为:它们支持组件化;它们有强大的社区支持;它们有很多(基于框架的)第三方库来解决问题;它们有很多(很好的)第三方组件;它们有浏览器扩展工具来帮助调试;它们适合做单页应用。 Keeping...

    Neilyo 评论0 收藏0
  • 你应该要知道Vue.js

    摘要:具体步骤实现将需要的数据对象进行递归遍历,包括子属性对象的属性,都加上和。综上,在性能上的收益并不是最主要的,更重要的是它使得具备了现代框架应有的高级特性。 原文:你应该要知道的Vue.js 组件data为什么必须是函数? 因为组件可能被多处使用,但他们的data是私有的,所以每个组件都要return一个新的data对象 组件通信 父子组件通信:$on、$emit 非父子组件的通信...

    张春雷 评论0 收藏0
  • Vue.js源码角度再看数据绑定

    摘要:在学习过程中,为加上了中文的注释,希望可以对其他想学习源码的小伙伴有所帮助。数据绑定原理前面已经讲过数据绑定的原理了,现在从源码来看一下数据绑定在中是如何实现的。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。文章的原地址:https://github.com/answershuto/le...

    elina 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<