【Vue原理】调试Vue源码

写文章不容易,点个赞呗兄弟 专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧 研究基于 Vue版本 【2.5.17】数组

若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧函数

【Vue原理】响应式原理 - 白话版学习

本文打算 白话文的形式讲解 Vue 的响应式系统原理,尽可能不涉及源码。code

只阐述工做流程,不想内容过多过于繁杂,致使你们会没有什么阅读的兴趣。对象

因此我从此打算把每个内容分红 白话版和 源码版。blog

白话版,就是让你们不用花费太多脑力,不用消耗太多时间,就能轻松地看完并大体了解内容。图片

有时间精力的人能够阅读源码版 ,而后本身参考源码,来进行研究学习。有什么错误的地方,感谢你们可以指出get


<br> <br>源码

响应式系统

咱们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。工作流

什么是响应式,也便是说,数据发生改变的时候,视图会从新渲染,匹配更新为最新的值。

也正是由于这个系统,让咱们能够脱离界面的束缚,只须要操做数据。

咱们能够问出下面三个问题

一、Vue 是怎么知道数据改变?

二、Vue 在数据改变时,怎么知道通知哪些视图更新?

三、Vue 在数据改变时,视图怎么知道何时更新?

问题的谜底将在下面一一解开

如今,我将会讲解三个重要的概念

Object.defineProperty,依赖收集,依赖更新

<br> <br>

Object.defineProperty

这个方法,是 Vue 响应式系统的精髓,骨髓,脑髓

使用 Object.defineProperty 能够为对象中的每个属性,设置 get 和 set 方法

Object.defineProperty 能够为属性设置不少特性,例如 configurable,enumerable,可是如今不过多解释,重点只放在 get 和 set

<br>

那么 get 和 set 方法有什么用?

get 值是一个函数,当属性被访问时,会触发 get 函数

set 值一样是一个函数,当属性被赋值时,会触发 set 函数

<br>

举个例子
var obj={    
    name:"神仙朱"
}
Object.defineProperty(obj,"name",{
    get(){        
        console.log("get 被触发")
    },
    set(val){        
        console.log("set 被触发")
    }
})

当我访问 obj.name 时,会打印 ' get 被触发 '

当我为 obj.name 赋值时,obj.name = 5,会打印 ' set 被触发 '

这即可以回答了我开篇的第一个问题

Vue 是怎么知道数据改变的呢?

恩,Vue 在 属性的 set 方法中作了手脚,于是当数据改变时,触发 属性的 set 方法,Vue 就能知道数据有改变


<br> <br>

依赖收集

<br>

简单地说

data 中的声明的每一个属性,都拥有一个数组,保存着 谁依赖(使用)了 它

<br>

举个例子
new Vue({    
    data(){        
        return {            
            name:"神仙朱"        
        }    
    }
})

而后 页面A 引用了name

<div>{{name}}</div>

此时,name 把 页面 A 存在它的后宫中(这个页面依赖我)

<br>

为何呢?

由于它知道谁依赖它以后,它就能够在发生改变的时候,通知 依赖它的页面,从而让页面完成更新

<br>

TIP

实际上,会依赖 name 的地方,不仅是页面,还会有 computed,watch.... 等等,可是这里咱们所有使用页面一词替代

这就是依赖收集,把 依赖了我(使用了个人东西),通通保存起来。

但是,保存在哪里,具体保存的是什么东西,咱们这里暂时不深刻,由于这是白话文。

我按上面的例子,从Vue 内部打印一份数据供你们简单了解便可

在这里插入图片描述 能够看到,name 属性,使用了 一个 dep 保存了 页面A 这个依赖,而保存的其实是 页面A的 Watcher。

<br>

TIP

简单说一下,watcher 是什么,每一个 Vue 实例都会拥有一个专属的 watcher,可用于实例更新

<br>

总结一下

一、data 中每一个声明的属性,都会有一个 专属的依赖收集器 subs

二、当页面使用到 某个属性时,页面的 watcher 就会被 放到 依赖收集器 subs 中

数据 是在何时进行 收集依赖 的呢?

答案是,ObjectdefineProperty - get

当 页面 A 读取了 name 时,会触发 name 的 get 函数,此时,name 就会保存 页面A 的 watcher 啦!

这即可以回答了我开篇的第二个问题

Vue 在数据改变时,怎么知道通知哪些视图更新?

恩,通知那些存在 依赖收集器中的 视图


<br> <br>

依赖更新

依赖更新,就是,通知全部的依赖进行更新

通过上面的讲解,咱们都知道,每一个属性都会保存有一个 依赖收集器 subs

而这个 依赖收集器,是用来在 数据变化时,通知更新的

数据 是在 何时进行 依赖更新 的呢?

答案是,Object.defineProperty - set

<br>

以上面的 Vue 实例 为例

当 name 改变的时候,name 会遍历本身的 依赖收集器 subs,逐个通知 watcher,让 watcher 完成更新

这里 name 会通知 页面A,页面A 从新读取新的 name ,而后完成渲染

<br>

这即可以回答了我开篇的第二个问题

Vue 在数据改变时,视图怎么知道何时更新?

恩,在数据变化触发 set 函数时,通知视图,视图开始更新

<br>

简单总结

一、Object.defineProperty - get ,用于 依赖收集

二、Object.defineProperty - set,用于 依赖更新

三、每一个 data 声明的属性,都拥有一个的专属依赖收集器 subs

四、依赖收集器 subs 保存的依赖是 watcher

五、watcher 可用于 进行视图更新


<br> <br>

最后

哈哈,最近好多的人都说我很高产,其实个人文章就是个人笔记,我作了不少笔记,可是个人笔记样式不堪入目,因此发文章须要排版,并且部份内容须要写得更加详细一些,所以须要更多的时间去验证研究,因此有时懒得发文章。

谢谢个人每个粉丝的支持,我一直之内容高质量,排版看得舒服 为目标,对待每一篇文章,因此很是耗时,可是我很认真。

若是发现有错误,说得不对的地方,很是感谢可以指出,本人会有重谢哈哈哈,很是欢迎一块儿探讨学习

公众号

相关文章
相关标签/搜索