写文章不容易,点个赞呗兄弟 专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧 研究基于 Vue版本 【2.5.17】数组
若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧函数
本文打算 白话文的形式讲解 Vue 的响应式系统原理,尽可能不涉及源码。code
只阐述工做流程,不想内容过多过于繁杂,致使你们会没有什么阅读的兴趣。对象
因此我从此打算把每个内容分红 白话版和 源码版。blog
白话版,就是让你们不用花费太多脑力,不用消耗太多时间,就能轻松地看完并大体了解内容。图片
有时间精力的人能够阅读源码版 ,而后本身参考源码,来进行研究学习。有什么错误的地方,感谢你们可以指出get
<br> <br>源码
咱们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。工作流
什么是响应式,也便是说,数据发生改变的时候,视图会从新渲染,匹配更新为最新的值。
也正是由于这个系统,让咱们能够脱离界面的束缚,只须要操做数据。
咱们能够问出下面三个问题
一、Vue 是怎么知道数据改变?
二、Vue 在数据改变时,怎么知道通知哪些视图更新?
三、Vue 在数据改变时,视图怎么知道何时更新?
问题的谜底将在下面一一解开
如今,我将会讲解三个重要的概念
Object.defineProperty,依赖收集,依赖更新
<br> <br>
这个方法,是 Vue 响应式系统的精髓,骨髓,脑髓
使用 Object.defineProperty 能够为对象中的每个属性,设置 get 和 set 方法
Object.defineProperty 能够为属性设置不少特性,例如 configurable,enumerable,可是如今不过多解释,重点只放在 get 和 set
<br>
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>
实际上,会依赖 name 的地方,不仅是页面,还会有 computed,watch.... 等等,可是这里咱们所有使用页面一词替代
这就是依赖收集,把 依赖了我(使用了个人东西),通通保存起来。
但是,保存在哪里,具体保存的是什么东西,咱们这里暂时不深刻,由于这是白话文。
我按上面的例子,从Vue 内部打印一份数据供你们简单了解便可
能够看到,name 属性,使用了 一个 dep 保存了 页面A 这个依赖,而保存的其实是 页面A的 Watcher。
<br>
简单说一下,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>
当 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>
哈哈,最近好多的人都说我很高产,其实个人文章就是个人笔记,我作了不少笔记,可是个人笔记样式不堪入目,因此发文章须要排版,并且部份内容须要写得更加详细一些,所以须要更多的时间去验证研究,因此有时懒得发文章。
谢谢个人每个粉丝的支持,我一直之内容高质量,排版看得舒服 为目标,对待每一篇文章,因此很是耗时,可是我很认真。
若是发现有错误,说得不对的地方,很是感谢可以指出,本人会有重谢哈哈哈,很是欢迎一块儿探讨学习