摘要:所以我今后打算把每一个内容分成白话版和源码版。有什么错误的地方,感谢大家能够指出响应式系统我们都知道,只要在实例中声明过的数据,那么这个数据就是响应式的。什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。
写文章不容易,点个赞呗兄弟
专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧
研究基于 Vue版本 【2.5.17】
如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧
【Vue原理】响应式原理 - 白话版
本文打算 白话文的形式讲解 Vue 的响应式系统原理,尽量不涉及源码。
只阐述工作流程,不想内容过多过于繁杂,导致大家会没有什么阅读的兴趣。
所以我今后打算把每一个内容分成 白话版和 源码版。
白话版,就是让大家不用花费太多脑力,不用消耗太多时间,就能轻松地看完并大致了解内容。
有时间精力的人可以阅读源码版 ,然后自己参考源码,来进行研究学习。有什么错误的地方,感谢大家能够指出
响应式系统我们都知道,只要在 Vue 实例中声明过的数据,那么这个数据就是响应式的。
什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。
也正是因为这个系统,让我们可以脱离界面的束缚,只需要操作数据。
我们可以问出下面三个问题
1、Vue 是怎么知道数据改变?
2、Vue 在数据改变时,怎么知道通知哪些视图更新?
3、Vue 在数据改变时,视图怎么知道什么时候更新?
现在,我将会讲解三个重要的概念
Object.defineProperty,依赖收集,依赖更新
Object.defineProperty这个方法,是 Vue 响应式系统的精髓,骨髓,脑髓
使用 Object.defineProperty 可以为对象中的每一个属性,设置 get 和 set 方法
Object.defineProperty 可以为属性设置很多特性,例如 configurable,enumerable,但是现在不过多解释,重点只放在 get 和 set
那么 get 和 set 方法有什么用?
get 值是一个函数,当属性被访问时,会触发 get 函数
set 值同样是一个函数,当属性被赋值时,会触发 set 函数
举个例子
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 就能知道数据有改变
依赖收集简单地说
data 中的声明的每个属性,都拥有一个数组,保存着 谁依赖(使用)了 它
举个例子
new Vue({ data(){ return { name:"神仙朱" } } })
然后 页面A 引用了name
{{name}}
此时,name 把 页面 A 存在它的后宫中(这个页面依赖我)
为什么呢?
因为它知道谁依赖它之后,它就可以在发生改变的时候,通知 依赖它的页面,从而让页面完成更新
TIP
实际上,会依赖 name 的地方,不只是页面,还会有 computed,watch.... 等等,但是这里我们全部使用页面一词替代
这就是依赖收集,把 依赖了我(使用了我的东西),统统保存起来。
可是,保存在哪里,具体保存的是什么东西,我们这里暂时不深入,因为这是白话文。
我按上面的例子,从Vue 内部打印一份数据供大家简单了解即可
可以看到,name 属性,使用了 一个 dep 保存了 页面A 这个依赖,而保存的实际上是 页面A的 Watcher。
TIP
简单说一下,watcher 是什么,每个 Vue 实例都会拥有一个专属的 watcher,可用于实例更新
总结一下
1、data 中每个声明的属性,都会有一个 专属的依赖收集器 subs
2、当页面使用到 某个属性时,页面的 watcher 就会被 放到 依赖收集器 subs 中
数据 是在什么时候进行 收集依赖 的呢?
答案是,ObjectdefineProperty - get
当 页面 A 读取了 name 时,会触发 name 的 get 函数,此时,name 就会保存 页面A 的 watcher 啦!
这便可以回答了我开篇的第二个问题
Vue 在数据改变时,怎么知道通知哪些视图更新?
恩,通知那些存在 依赖收集器中的 视图
依赖更新依赖更新,就是,通知所有的依赖进行更新
经过上面的讲解,我们都知道,每个属性都会保存有一个 依赖收集器 subs
而这个 依赖收集器,是用来在 数据变化时,通知更新的
数据 是在 什么时候进行 依赖更新 的呢?
答案是,Object.defineProperty - set
以上面的 Vue 实例 为例
当 name 改变的时候,name 会遍历自己的 依赖收集器 subs,逐个通知 watcher,让 watcher 完成更新
这里 name 会通知 页面A,页面A 重新读取新的 name ,然后完成渲染
这便可以回答了我开篇的第二个问题
Vue 在数据改变时,视图怎么知道什么时候更新?
恩,在数据变化触发 set 函数时,通知视图,视图开始更新
简单总结
1、Object.defineProperty - get ,用于 依赖收集
2、Object.defineProperty - set,用于 依赖更新
3、每个 data 声明的属性,都拥有一个的专属依赖收集器 subs
4、依赖收集器 subs 保存的依赖是 watcher
5、watcher 可用于 进行视图更新
最后如果发现有错误,说得不对的地方,非常感谢能够指出,本人会有重谢哈哈哈,非常欢迎一起探讨学习
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105085.html
摘要:如果没有缓存,我们将不可避免的多次执行的现在我们要开始讲解,是如何判断是否使用缓存的首先计算后,会把计算得到的值保存到一个变量中。当使用缓存时,就直接返回这个变量。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或...
写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【Vue原理】Props - 源码版 今天记录 Props 源码流程,哎,这东西,就算是研究过了,也真是会随着时间慢慢忘记的。 幸好我做...
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧如果你觉得排版难看,请点击下面公众号 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基...
摘要:而是在初始化时,在读取了监听的数据的值之后,便立即调用一遍你设置的监听回调,然后传入刚读取的值设置了时,如何工作我们都知道有一个选项,是用来深度监听的。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下...
摘要:通常会做很多判断来选择存在的类型,比如判断等是否存在,而选择他为微任务类型但是可能宏微任务最后都是,因为他是保守兼容处理。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【V...
阅读 2208·2021-09-23 11:52
阅读 1873·2021-09-02 15:41
阅读 2999·2019-08-30 10:47
阅读 1958·2019-08-29 17:14
阅读 2305·2019-08-29 16:16
阅读 3172·2019-08-28 18:29
阅读 3396·2019-08-26 13:30
阅读 2592·2019-08-26 10:49