0


【VUE】源码阅读指南(内附逐行注释解析源码免费下载)

为了考虑到有些同学比较追求效率,把注释版源码链接放在最前面,供大家直接下载使用( 建议至少看看流程分析部分 ):

ccuuu/vue-learning: vue超详细逐行解析版源码 (github.com)https://github.com/ccuuu/vue-learning**使用的vue版本为:2.6.14**

写在前面

学习源码是必须的吗?

这是一个灵魂拷问。学习源码是必须的吗?肯定不是。甚至我可以这么说,学习完vue源码,并不会让你在短时间内有质的提升。一门技术,一定是基础知识加上经验组成的。而阅读源码,只是在一定程度上补充基础知识,它带来的好处是隐性的。在工作中你或许会发现,很多经验老道的程序员从未看过源码,但代码依旧书写的异常优秀,你必然不可能通过源码而短时间达成他们的开发水平。

那么为什么要学习源码呢?不知你是否有听说过技术栈这个概念,发明这个词简直是天才,因为一个人的技术,真的就像是一个栈结构。计算机基础是最栈底的技术支持,而浏览器的底层原理次之,接着是JS,然后是vue、react等框架,最后可能还有ElementUI等基于框架的技术。学习vue源码,能让你站在vue的下层去对这个框架有更深的了解,从而在vue及其上层技术的使用上更加得心应手,但最重要的一点,是在学习过程中,会不断刷新你对JS的认识,隐性的提升JS水平。

那么再回到这个问题,学习源码是必须的吗?不是,但是是有必要的。它能让你的整个知识框架更成体系,会让你的技术栈结构更加的牢固。而随着你的底层技术不断提升,栈顶的的一些工具类也就不是会不会,而只是需不需要的问题了。

能点进这篇文章的你,一定是对技术有一定好奇与追求的。希望你我都能够一直保持这份热情与初衷。

如何学习

首先,一定不是直接使用这份有注释的版本。请通过自己的代码阅读能力去解读。这在一开始或许进程会很慢,但是一定会给你带来很深的理解,并且随着不断的阅读,你的代码感知能力也会不断地增强。而注释版本,尽量只做最后的手段。随着不断地深入学习,或许在某一个时间点,你可以完全抛弃注释。

基于以上理由,建议你从github上拉取一份源码。最好是版本相同,因为不同的版本代码会有所不同,可能会增加一定的学习难度。

对于逻辑上有不懂的,可以参考我的其他博客。我会尽量详细的去分享一些重要的知识点,但是同样,一定只是结合理解,而不是先看后学。

如果有其他疑问,可以随时私信我,或者评论留言。

文件结构分析

我们先分析文件目录。

dist为构建输出文件,即运行时的那一份。我们只需要关注src目录下的文件即可。

进入到src内部:
compiler:编译相关模块,也就是template模板转换为render函数的地方;
core:核心模块,vue的初始化、整个生命周期都在这里实现;
platforms:平台化模块,分为web和weex,而我们只需要关注web即可;
server:服务端渲染模块,我们可以无需关注;
sfc:对单文件组件的处理模块。同样,无需关注;
shared:一些公用的工具方法。

总结来说,在上述的文件中,我们需要重点关注的只有:compiler、core、platforms、shared。

再来细看这几个文件:

compiler文件

整个compiler的核心作用就是生成render函数。而在该模块中的重点逻辑为 HTMLParser、parse、optimization、generate。在该文件中,会存在大量的高阶函数,在阅读该模块代码的时候也是以充分学习到函数式编程的思想。以下是对几个核心文件的简单介绍:
codengen:主要功能是用AST生成render函数字符串;
directives:存放一些指令的处理逻辑,如v-bind、v-model、v-on等;
parser:主要功能是将template模板编译为AST;
index:compiler的入口文件;
optimizer:用来对AST做一些剪枝操作的标记处理,会在codengen和vnode的patch中用到;
to-function:将codengen生成的render函数字符串用new Function的方式最终生成render函数。

core文件

core模块为整个vue的核心模块,其中几乎包含了vue的所有核心内容。如vue实例化的选项合并,data、computed等属性的初始化,Watcher、Observer的实现、vue实例的挂载等等。内容很多,因此我们需要重点分析该模块:

components:名称取的比较让人迷惑,但其实他并不是组件创建或更新相关的模块,在其内部只存在一个keep-alive;

glodbal-api:存在一些全局api,如extend、mixin等等,也包括assets属性(component、directive)的初始化逻辑;

instance:core模块中的核心,也是整个vue初始化的地方。包括了各种属性、事件的初始化,以及钩子函数的调用。其中的index文件,就是vue构造函数所在。而其他的文件,就像是一个个工厂,对vue进行层层加工,即初始化参数、初始化属性和方法等等;

observer:响应式的实现所在,也就是数据劫持、依赖添加的具体逻辑实现。在我之前的博客中经常说到的Watcher、Dep、Observer都存放在这个文件中;

util:工具文件。各种工具函数的所在。其中nextTick函数就存放在这儿;

vdom:也就是虚拟DOM(vonde)相关内容模块。包括普通节点vnode、component vnode、functional component等的初始化、patch函数等等。

paltforms文件和shared文件

paltforms文件的逻辑不多,也不复杂。其中最主要的就是改写mount函数、合并一些初始化选项、做一些差异化的处理,如属性和指令等。大家可以只关注web相关的内容即可。

shared文件用来存放一些共享的工具函数(我个人最喜欢cache函数就放在这里)。

流程分析

整个vue相对而言还是比较庞大的。合适的阅读顺序能为你省下不少精力。以下是我按照个人阅读经验梳理的顺序:

本想整理一份尽可能详细清晰的流程图,但是似乎其中的依赖关系比想象的复杂。我尽量将主线的顺序给梳理清楚,当然肯定会有细节上的疏漏。仅作参考。

阅读技巧

你会发现,很多时候一些知识点,一些意图,是你当时无论如何都无法理解的。你可以采取两种方法:

深度优先。遇到不会的问题时,不断去深挖。但是这种模式效率相对会很低,不过优点是你的理解也会随着一次次深挖不断的加深;

广度优先。这种模式下,对于一些当时弄不懂的点,做“战术上轻视,战略上重视”,等学到该知识点相关联的知识点之后,再回过头来重新理解,或许会有豁然开朗的感觉。这种模式的整体效率较高,但是缺点是忽略成习惯了,会产生一种惰性心里,对一些能突破的知识可能也会习惯性的忽略。并且跳过的知识点多了,容易产生遗漏。

以下述的两个知识点为例:

function initComputed(vm: Component, computed: Object) {
  ...
  const watchers = (vm._computedWatchers = Object.create(null));
  ...
}

Vue.prototype.$watch = function (
  expOrFn: string | Function,
  cb: any,
  options?: Object
): Function {
  ...
  const watcher = new Watcher(vm, expOrFn, cb, options);
  ...
}

对于Watcher和Dep这两个类,看起来并不是短时间内能攻破的,但是它其实又的确是需要你在学习watch和computed的同时,甚至是在他们俩之前(defineReactive的时候)就需要去琢磨透的,否则对于这一类知识点的了解肯定不够到位。

export function mountComponent(
  vm: Component,
  el: ?Element,
  hydrating?: boolean
): Component {
  ...
  new Watcher(
    vm,
    vm._update(vm._render(), hydrating),
    noop,
    {
      before() {
        if (vm._isMounted && !vm._isDestroyed) {
          callHook(vm, "beforeUpdate");
        }
      },
    },
    true /* isRenderWatcher */
  );
  ...
}

而对于组件实例的Watcher,如果用深度学习的方法,会让你在不恰当的时间点跳过前置知识提前阅读compiler和generate相关的内容。这种情况会让阅读的复杂度大大提升。因此在这里其实合适的做法应该是先忽略 vm._update(vm._render(), hydrating) 这一行代码,只是知道他是用来update的即可,而主要关注核心的Watcher功能的实现。

建议大家自行判断,选择性的结合两种模式去阅读源码。

一些建议

或许你水平很高,在源码的阅读过程中发现也会有写法粗糙的地方;又或许阅读源码对现在的你还是一种挑战,会有各种各样的困难。但是不管怎么样,心态请放平。源码没有想象的那么神圣,他是人写的就也是人看的,遇到困难尝试去突破,不要妄自菲薄觉得自己不行。当然源码是人写的肯定就会有不好的地方,甚至是bug。没必要去嘲讽,没必要发现一些问题就窃窃自喜。有些人非科班毕业20来岁就做出了vue,而有些人用找到源码的bug当作宣传自己的资本。大可不必。去学习别人优秀的写法和前卫的思想即可。

写在最后

一些废话,可以跳过...

这是我vue源码解读系列的...。我自己也不记得写了几篇了。这中间的每一篇我都是很用心的去创作。我的初衷很简单,给那些想去学习源码的人提供帮助。

记得我最初决定阅读源码的目的也很单纯:去更加了解vue。由于个人的开发习惯,我总是会写出一些奇思妙想的代码,因此也总是会遇到很多奇奇怪怪的问题。那个时候我总是一有问题就去请教带我的师傅。可是到后来,遇到的问题越来越奇怪,师傅也解答不了了,于是我就寄希望于强大的网友。但是最终发现,这个时候就只能寄希望于别人也同样遇到这个问题,并且好心分享上传了心得。而大多数情况,都是查不到的。但是我本身又是一个喜欢刨根问底的人。于是便开启了我vue源码的阅读之路。

在最开始,充满了困难。可以说寸步难行,我甚至连入口文件都在网上找了半天才找到。当时想借助网友对源码的分享,来帮助我源码计划的实行,但是后来发现,网上对源码解读的博客是少之又少,而有的,大多数也是写的比较浅,不太符合我个人的学习习惯。没办法,那就只能硬着头皮自己啃。不过幸运的是,没过多久,偶然的我认识到了霍春阳,一位对vue研究极深的博主。他的博客对我前期帮助很大,并且更幸运的是他的态度和我很相似,都喜欢对每一个点很细致的去钻研。因此,我很喜欢看他的博客,也是在他博客的引导下,我完成了从纯小白到开始了解源码的过度。

而开始上道了之后,剩下的就只是坚持的问题。我开始享受在源码中去学习的过程。当然困难依旧很多,依旧很多次我产生放弃的想法。程序员应该都会懂我这种阅读别人代码的痛苦。何况对方还是水平完全碾压我的存在。我不断地在了解到高精尖知识而带来的兴奋,以及知识体系被碾压而产生的深深自卑中反复。幸运的是我最终坚持下来了。

在看完源码的那一刻,我最想去做的一件事情,就是将自己对vue粗浅的理解及对vue学习的一些经验整理出来,分享给需要的人。理由也很简单,如果有一个像我之前一样想去学习源码,但是又无从下手的人,在不小心翻到我的博客之时,能从中得到一些帮助。

不过在我写博客的过程中,也总是会感到深深的无奈。我每一篇博客都会花大量的时间去整理。图一张张的画,内容逐字逐句的敲。但是写出来的东西,好像并不受欢迎。我总是告诉自己,不忘自己的初心,将想要分享的内容写出来才是我的根本目的。但是又忍不住会去关注浏览量,点赞量。有时候一篇博客写出来,甚至还没有某些发两张生活照的浏览量高。不过无奈之下,我依旧会坚持vue源码系列的更新。这是给自己的一种交代。

洋洋洒洒写了一大堆,也算是吐露了自己的心声吧。

最后,祝准备阅读源码的你,能成功跨越这座小山。

友情链接

首先,向大家极力推荐霍春阳的博客:

写在前面 - Vue技术内幕逐行级别的 Vue 源码分析http://caibaojian.com/vue-design/art/春阳目前是vue3的核心开发之一,他对vue的理解程度肯定是毋庸置疑的。并且上述博客对vue的分析深入浅出,又细致入微,我目前未在网上发现有任何关于vue的解读能与这一篇相媲美。

霍春阳也是《vue.js设计与实现》(尤大大钦点的书)的作者。这本书是值得大家深入学习的,在此也推荐给大家。

然后是vue的相关链接:

vue源码下载地址https://github.com/vuejs/vuevue2官方文档Vue.js - The Progressive JavaScript Frameworkhttps://cn.vuejs.org/index.html

最后附上我个人的相关博客链接:

【VUE】源码分析 - computed计算属性的实现原理_依然范特西fantasy的博客-CSDN博客

【VUE】源码分析 - watch侦听器的实现原理_依然范特西fantasy的博客-CSDN博客

【VUE】源码分析 - 数据劫持的基本原理_依然范特西fantasy的博客-CSDN博客

【VUE】源码分析 - 剖析$nextTick原理及VUE的刷新机制_依然范特西fantasy的博客-CSDN博客

【VUE】源码分析 - vue中的 HTMLParser,模板解析的第一步_依然范特西fantasy的博客-CSDN博客


本文转载自: https://blog.csdn.net/ccuucc/article/details/124981766
版权归原作者 依然范特西fantasy 所有, 如有侵权,请联系我们删除。

“【VUE】源码阅读指南(内附逐行注释解析源码免费下载)”的评论:

还没有评论