写文章不容易,点个赞呗兄弟 专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧 研究基于 Vue版本 【2.5.17】数组
若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧缓存
今天咱们用白话文解读 computed 的工做原理,轻松快速理解 computed 内部工做原理。由于若是你不懂原理,有时候作项目,碰到奇怪的问题,真的不知道怎么回事性能
要理解 computed 的工做原理,只须要理解下面三个问题学习
一、computed 也是响应式的设计
二、computed 如何控制缓存cdn
三、依赖的 data 改变了,computed 如何更新blog
开始咱们今天的讲解,但愿你认真看完会有收获图片
"必须有收获谢谢,否则我不白写了吗兄弟"get
在这里,我先告诉你,computed 实际上是一个 月老,专门牵线
什么是响应式,不知道的童鞋请参考我之前的文章
你给 computed 设置的 get 和 set 函数,会跟 Object.defineProperty 关联起来
因此 Vue 能捕捉到 读取computed 和 赋值computed 的操做
读取computed 时,会执行你设置的 get 函数,可是并无这么简单,由于还有一层缓存的操做
赋值 computed 时,会执行你设置的 set 函数,这个就比较简单,会直接把 set 赋值给 Object.defineProperty - set
咱们都知道,computed 是有缓存的,官方已经说明
"计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会从新求值"
"咱们为何须要缓存?假设咱们有一个性能开销比较大的计算属性 A,它须要遍历一个巨大的数组并作大量的计算。而后咱们可能有其余的计算属性依赖于 A 。若是没有缓存,咱们将不可避免的屡次执行 A 的 getter"
如今咱们要开始讲解,Computed 是如何判断是否使用缓存的
首先 computed 计算后,会把计算获得的值保存到一个变量中。读取 computed 时便直接返回这个变量。
当使用缓存时,就直接返回这个变量。当 computed 更新时,就会从新赋值更新这个变量
computed 控制缓存的重要一点是 【脏数据标志位 dirty】,dirty 是 watcher 的一个属性
当 dirty 为 true 时,读取 computed 会从新计算
当 dirty 为 false 时,读取 computed 会使用缓存
1一开始每一个 computed 新建本身的watcher时,会设置 watcher.dirty = true,以便于computed 被使用时,会计算获得值
2当 依赖的数据变化了,通知 computed 时,会设置 watcher.dirty = true,以便于其余地方从新渲染,从而从新读取 computed 时,此时 computed 从新计算
3computed 计算完成以后,会设置 watcher.dirty = false,以便于其余地方再次读取时,使用缓存,免于计算
首先,data 和 computed 本质上差很少,都是数据,都须要被使用。
当 A 引用 B 的时候,B 会收集 A 的watcher,不明白的能够参考以前文章
【Vue原理】响应式原理 - 白话版
如今 页面A 引用了 computed B,computed B 依赖了 data C
像是这样,A->B->C 的依赖顺序
一开始个人想法是,data C 开始变化后.......
1通知 computed B 更新,而后 computed B 开始从新计算
2接着 computed B 通知 页面A更新,而后从新读取 computed
一条链式的操做? C -》 B -》 A 这样的执行顺序吗?
答案:不是
其实真正的流程是,data C 开始变化后.......
1通知 computed B watcher 更新,其实只会重置 脏数据标志位 dirty =true,不会计算值
2通知 页面 A watcher 进行更新渲染,进而从新读取 computed B ,而后 computed B 开始从新计算
data C 的依赖收集器会同时收集到 computed B 和 页面 A 的 watcher
这就是 Vue 设计的巧妙之处了,也就是我开始讲的,computed 实际上是一个 月老
在 页面 A 在读取 computed B 的时候,趁机把 页面A 介绍给 data C ,因而 页面A watcher 和 data C 间接牵在了一块儿,因而 data C 就会收集到 页面A watcher
至于怎么牵在一块儿,白话版不会多说,不浪费你们的脑力
被依赖通知更新后,重置 脏数据标志位 ,页面读取 computed 时再更新值
1computed 经过 watcher.dirty 控制是否读取缓存
2computed 会让 【data依赖】 收集到 【依赖computed的watcher】,从而 data 变化时,会同时通知 computed 和 依赖computed的地方