带你阅读Vue3.0响应式系统系列源码1
主题:绪论
引言
首先笔者问自己,为什么要阅读一下你这个教程,网络上有很多教程,然而这个教程有什么亮点?
网络上是有不少Vue3.0、Vue2.0源码阅读的教程,我也有去看了一下,有的写得也很不错,但是他们有一个共同的点,就是逐行代码进行解释讲解。这样好不好?好,但是还是差了点东西:逐行代码进行讲解的话,阅读的人能够很清楚知道每一行代码的作用、每一个方法的作用。但是东西讲的越细致,就很难有那种宏观上讲解,整个系统模块之间的联系、嵌套就很难表达处理。可能读者阅读到最后,每个方法都会了,都理解了,但是就是对整个流程不清楚。
如果对于新手,刚刚接触源码不久,一行一行代码进行讲解,很有效,因为我2.0源码就是这么来进行学习的。但是如果面对有一定经验的人,那未必是好事。因为他们一看代码自己就能看懂,他们的想要的内容则是高于看懂代码:比如说整体的框架是怎么样子的?整体的设计思想是什么样子的?等等。
而本教程根据个人的经验、思考尽量从分类、设计思想、对比等几方面来进行讲解Vue3.0预览版的源码,而不是从头到尾抓住源码进行一行一行解析,其中亮点有如下:
- 将作用相同的东西进行分类,比如代理
handler
、effect
类型等。 - 根据阅读经验,将Vue2.0与Vue3.0都同一个代码\功能的实现进行对比,并且分别讲解其优缺点。
- 对核心代码进行讲解(这是必要的)。
- 对重要的数据结构及其构建进行说明。
至于本想要像其它教程一样一行一行代码“翻译”的原因有两个:
- 这是预览版代码,代码很容易进行小改动,但是设计架构、思想却很难进行改变,延长本教程的有用时间
- 3.0代码太多了,没有那么多时间。
阅读本教程,希望能够达到对packages/reactivity
下面的代码,也就是响应式代码的整体结构基本了解,并且能够在脑海里面进行响应式流程的执行“复盘”。
1.本系列将如何进行讲解?
每个框架都是从初期的简化版本不断通过用户使用、反馈来进行升级换代的,Vue框架也不例外。Vue框架到现在已经出了三个大版本,笔者是从Vue2.0时候开始使用并且阅读2.0的源码,所以算是对这个版本的正常版本的核心代码比较了解。Vue3.0的预览版出了大概两三个月了,笔者前几天才得知有这个预览版本,所以凭着兴趣去看了一下源码的响应式系统。
通过阅读源码,发现Vue3.0和Vue2.0相比,虽然把代码结构、项目架构完全修改了,但是看完后,发现虽然实现的方式不同,但是思路还是按照Vue原本的实现思路相同,所以总结起来就是:换汤不换药,还加了点糖。
注意:本系列只将可读可写的数据相应系统,对于只读的数据相应系统由于很大程度上是重复的,那么不进行讲解。
2.Vue3.0和Vue2.0的响应式系统区别是什么?
Vue2.0和Vue3.0的区别的话,这里有一个连接来进行介绍:解读 Vue 3.0 的变化 。对于响应式系统来说,最大的区别有两个:
- 全部用TypeScript重构。
- 利用代理(
Proxy
)和反射(Reflect
)来替换掉Vue2.0的Object.defineProperty。
利用TypeScript进行重构,使得代码的可读性更强。而利用ES6的Proxy
拦截属性和Reflect
来实现数据劫持,提高了框架的性能,并且做到了之前不能做到的事情。通过阅读这份代码后,发现相比于Vue2.0,3.0的一个明显特点:
- 耦合度降低:相比于上一代,这一代源码中,将很多东西进行抽象化,然后通过策略模式进行填充从而实现(个人觉得还可以通过继承抽象类的方式进行处理的达到相同的目的)。比如
effect
(也就是2.0的Watcher
)实例的scheduler
是一个空的属性,由传进来的配置的执行函数来决定调用方式(这个在被观察对象触发依赖的时候如何执行的时候进行说明)。 - 分类更清晰,更容易让读者进行分类。这样更有利于普通编程爱好者对框架源码的整体把握(虽然注释还是那么少)。
3.Vue3.0和Vue2.0的响应式相比,优点是什么?
Vue3.0与Vue2.0相比,优点如下:
- 做到了Vue2.0不能实现,或者能实现,但是要花费大量资源实现的事情,如2.0是不对直接修改数组下标的时候进行响应的,而Vue3.0支持,Vue2.0中没有考虑到容器型数据结构,如
Map
、Set
、WeakMap
、WeakSet
四个容器型数据结构,而3.0一并支持。 - 避免了Vue2.0的一些漏洞和缺陷
- 不需要在每个对象上进行添加某个标志属性,这样在运行的时候不会被随意修改依赖触发函数,对于数据比较安全。(3.0是存在某个闭包里面的,理论上人工是找不到存放对象的)。
- 不需要对对象的每个属性都添加响应式数据,取而代之的是对对象进行代理拦截,代理拦截能够统一对对象的所有属性进行统一处理。这便是性能的提升。
这些点等到整个系列分析完毕后再用一章的时间来进行分析。
4.个人如何进行学习?
在这个系列中,我着重讲的部分是整个响应式的设计结构层次图、将同一种东西进行分类说明,帮助想要了解这个系统、并且要进行阅读的人进行理解。所以本系列出现代码的数量会很少。在学习本系列的时候,笔者建议读者这么来做:
- 如果你没看过代码,并且想要学好这部分源码,那么建议你使用ES6代理模式和反射实现数据响应系统。
- 个人在去年9月份的时候,根据个人的理解,写了一份ES6代理模式实现数据响应系统 我是按照自己的想法进行实现的,有很多与源码不同,但是有了这一份经历后,阅读源码变得简单了。
需要掌握的基础知识有:
- TypeScript
- JavaScript设计模式:策略模式、观察者模式等
- ES6的解构赋值、集合类、代理、反射、模块化等,基本上除了异步编程都要会用
- JavaScript引擎的运行机制:事件循环机制