vue2源码解析入门 (vue 2.6.14) (一)

 Vue 的初始化过程:
执行编译,生成 render 函数。
一系列的初始化,数据响应式化,触发对应的生命周期钩子。
执行挂载的逻辑,先生成虚拟 DOM,再生成真实 DOM,更新的逻辑也是这样,只不过多出了对比虚拟 DOM 的一个步骤

一、我们到 vue仓库 下载 Vue2.6.14 的源码。

https://github.com/vuejs/
先来看一下整体目录结构

 

 

 

二、首先通过 package.json 中的打包命令,我们可以找到完整版的 Vue 的入口文件。

在该文件中,看到vue用的是的rollup编辑的

rollup -w - c
--wacth | -w 开启文件监视 // 它检测到磁盘上单个模块已经改变,它会重新构建你的文件束

--config | -c 指定配置文件地址

(1)package.json

 (2)scripts/config.js

找到config.js文件,路径为scripts/config.js

需要拿到 --environment传入的环境变量,根据配置TARGET的配置选择 web-full-dev的配置

 

找到resole的封装找到对应的路径配置alias.js

(3)scripts/alias.js

 

(4)src/platforms/web/entry-runtime-with-compiler.js 

所以我们先来到 src/platforms/web/entry-runtime-with-compiler.js 文件

通过一层一层的分析,终于快要到vue的核心代码了

简单来看下,这个文件主要是扩展了 Vue.prototype.$mount 方法

 

根据源码,我们还可以得到一个小知识,就是如果 Vue 的 options 中同时传入 el, render, template,哪个优先级最高?

通过下面这段代码,我们可以发现,render 的优先级是最高的,因为如果是 render,则直接走到最下面的 mount 了,其次是 template,然后再是 el

 

 在src/platforms/web/entry-runtime-with-compiler.js 这个文件中看到引入的vue

 

 也就是这个文件src/platforms/web/runtime/index.js 文件

(5)src/platforms/web/runtime/index.js

这里有 2 个比较重要的方法

 

 可以看到,原始的 $mount 是在这里被赋值的,不过我们还没找到初始的 Vue 类,所以我们继续进入 src/core/index.js

 

 

 

 

 (6) src/core/index.js

 

 initGlobalAPI 定义了一些全局 API,比如 setuse 之类的,我们继续看 instance/index 中的代码。

三、原始的 Vue 

(7) src/core/instance/index.js

在这里,终于找到原始的 Vue 了

构造函数定义了一个Vue

 new Vue 的入口就是这里。

它调用了 _init 方法,而 _init 方法是 initMixin 混入进来的。

 

 找到initMixin

(8) src/core/instance/init.js

在这里,可以看到Vue 的初始化过程

 

 看一下源码中的 initState

 (9)src/core/instance/state.js

可以看到数据响应式的做法,初始化处理 data 的函数 initData()

这个 initData方法调用了proxy 和 observe

 (10)src/core/observer/index.js

来看看observe

 

 

 在构造函数中,发现每个被处理过的对象,都会挂上 _ob_ 这个 key,代表着 Observer 实例,

另外 this.dep = new Dep() 这个代码要关注下,即每个 Observer 有一个独有的 dep 依赖。

 

(11)  src/core/instance/lifecycle.js

  Watcher

每个组件只有一个 Watcher,当然用户也可能通过 watch 创建额外的。这里我们也可以看到组件的挂载过程,先调用 render 函数,那 render 生成虚拟 DOM,然后交给 _update 函数。

 

看下 _update 函数的逻辑,可以看到就是使用 _patch_ 来对比前后虚拟 DOM,然后生成真实 DOM,再进行渲染,patch 也就是我们常说的 diff

 

 

 (12)  src/core/observer/watcher.js

从构造函数中可以发现 this.get 方法的调用,pushTarget 用来设置 Dep.targetthis.getter 则是调用了传进来的更新函数

 

 

posted @ 2022-04-23 16:39  阿哲淘小子  阅读(918)  评论(0编辑  收藏  举报