带你阅读Vue3.0响应式系统源码1-绪论

1,523 阅读6分钟

带你阅读Vue3.0响应式系统系列源码1

主题:绪论

引言

​ 首先笔者问自己,为什么要阅读一下你这个教程,网络上有很多教程,然而这个教程有什么亮点?

​ 网络上是有不少Vue3.0Vue2.0源码阅读的教程,我也有去看了一下,有的写得也很不错,但是他们有一个共同的点,就是逐行代码进行解释讲解。这样好不好?好,但是还是差了点东西:逐行代码进行讲解的话,阅读的人能够很清楚知道每一行代码的作用、每一个方法的作用。但是东西讲的越细致,就很难有那种宏观上讲解,整个系统模块之间的联系、嵌套就很难表达处理。可能读者阅读到最后,每个方法都会了,都理解了,但是就是对整个流程不清楚。

​ 如果对于新手,刚刚接触源码不久,一行一行代码进行讲解,很有效,因为我2.0源码就是这么来进行学习的。但是如果面对有一定经验的人,那未必是好事。因为他们一看代码自己就能看懂,他们的想要的内容则是高于看懂代码:比如说整体的框架是怎么样子的?整体的设计思想是什么样子的?等等。

​ 而本教程根据个人的经验、思考尽量从分类、设计思想、对比等几方面来进行讲解Vue3.0预览版的源码,而不是从头到尾抓住源码进行一行一行解析,其中亮点有如下:

  1. 将作用相同的东西进行分类,比如代理handlereffect类型等。
  2. 根据阅读经验,将Vue2.0Vue3.0都同一个代码\功能的实现进行对比,并且分别讲解其优缺点
  3. 对核心代码进行讲解(这是必要的)。
  4. 对重要的数据结构及其构建进行说明。

至于本想要像其它教程一样一行一行代码“翻译”的原因有两个:

  1. 这是预览版代码,代码很容易进行小改动,但是设计架构、思想却很难进行改变,延长本教程的有用时间
  2. 3.0代码太多了,没有那么多时间。

阅读本教程,希望能够达到对packages/reactivity下面的代码,也就是响应式代码的整体结构基本了解,并且能够在脑海里面进行响应式流程的执行“复盘”。

1.本系列将如何进行讲解?

​ 每个框架都是从初期的简化版本不断通过用户使用、反馈来进行升级换代的,Vue框架也不例外。Vue框架到现在已经出了三个大版本,笔者是从Vue2.0时候开始使用并且阅读2.0的源码,所以算是对这个版本的正常版本的核心代码比较了解。Vue3.0的预览版出了大概两三个月了,笔者前几天才得知有这个预览版本,所以凭着兴趣去看了一下源码的响应式系统。

​ 通过阅读源码,发现Vue3.0Vue2.0相比,虽然把代码结构、项目架构完全修改了,但是看完后,发现虽然实现的方式不同,但是思路还是按照Vue原本的实现思路相同,所以总结起来就是:换汤不换药,还加了点糖

注意:本系列只将可读可写的数据相应系统,对于只读的数据相应系统由于很大程度上是重复的,那么不进行讲解。

2.Vue3.0和Vue2.0的响应式系统区别是什么?

Vue2.0Vue3.0的区别的话,这里有一个连接来进行介绍:解读 Vue 3.0 的变化 。对于响应式系统来说,最大的区别有两个:

  • 全部用TypeScript重构。
  • 利用代理(Proxy)和反射(Reflect)来替换掉Vue2.0Object.defineProperty

利用TypeScript进行重构,使得代码的可读性更强。而利用ES6Proxy拦截属性和Reflect来实现数据劫持,提高了框架的性能,并且做到了之前不能做到的事情。通过阅读这份代码后,发现相比于Vue2.0,3.0的一个明显特点:

  • 耦合度降低:相比于上一代,这一代源码中,将很多东西进行抽象化,然后通过策略模式进行填充从而实现(个人觉得还可以通过继承抽象类的方式进行处理的达到相同的目的)。比如effect(也就是2.0的Watcher)实例的scheduler是一个空的属性,由传进来的配置的执行函数来决定调用方式(这个在被观察对象触发依赖的时候如何执行的时候进行说明)。
  • 分类更清晰,更容易让读者进行分类。这样更有利于普通编程爱好者对框架源码的整体把握(虽然注释还是那么少)。

3.Vue3.0和Vue2.0的响应式相比,优点是什么?

Vue3.0Vue2.0相比,优点如下:

  • 做到了Vue2.0不能实现,或者能实现,但是要花费大量资源实现的事情,如2.0是不对直接修改数组下标的时候进行响应的,而Vue3.0支持,Vue2.0中没有考虑到容器型数据结构,如MapSetWeakMapWeakSet四个容器型数据结构,而3.0一并支持。
  • 避免了Vue2.0的一些漏洞和缺陷
    • 不需要在每个对象上进行添加某个标志属性,这样在运行的时候不会被随意修改依赖触发函数,对于数据比较安全。(3.0是存在某个闭包里面的,理论上人工是找不到存放对象的)。
    • 不需要对对象的每个属性都添加响应式数据,取而代之的是对对象进行代理拦截,代理拦截能够统一对对象的所有属性进行统一处理。这便是性能的提升。

这些点等到整个系列分析完毕后再用一章的时间来进行分析。

4.个人如何进行学习?

​ 在这个系列中,我着重讲的部分是整个响应式的设计结构层次图、将同一种东西进行分类说明,帮助想要了解这个系统、并且要进行阅读的人进行理解。所以本系列出现代码的数量会很少。在学习本系列的时候,笔者建议读者这么来做:

  • 如果你没看过代码,并且想要学好这部分源码,那么建议你使用ES6代理模式和反射实现数据响应系统
  • 个人在去年9月份的时候,根据个人的理解,写了一份ES6代理模式实现数据响应系统 我是按照自己的想法进行实现的,有很多与源码不同,但是有了这一份经历后,阅读源码变得简单了。

需要掌握的基础知识有:

  • TypeScript
  • JavaScript设计模式:策略模式、观察者模式等
  • ES6的解构赋值、集合类、代理、反射、模块化等,基本上除了异步编程都要会用
  • JavaScript引擎的运行机制:事件循环机制

5.本系列解读传送门

1.绪论

2.对象及数据结构分析

3.响应型数据诞生

4.依赖绑定以及触发依赖的执行策略

5.总结

附录1.Vue3.0代理如何对数组的原生方法进行观察

附录2.Vue3.0响应数据对象的构建过程(必读)