大家好,我是金同学。话不多说,直接进入主题。来跟我通过调试源码一步一步看 Vue 初始化实例成员和静态成员的过程,从中学习 Vue
的相关知识点。
准备工作
首先把仓库代码拉到你本地,仓库源码地址在这里
拉下仓库代码后,执行以下两步:
- 1、用
VsCode
打开仓库代码,先安装依赖,然后运行npm run dev
,这步为的是能在调试Vue
代码时看到源文件。 - 2、然后进到下图目录中,右击用
live-server
打开。
粮草先行 🛫 🛫 🛫
先主要复习下初始化过程涉及到的文件、函数等。
src/core/index.js
这个文件里面主要就是执行了
initGlobalAPI(Vue)
这个方法。initGlobalAPI(Vue)
方法里面可做了不少事情,主要就是初始化静态成员...
- 1、初始化了
Vue.config
对象 - 2、初始化静态方法
set/delete/nextTick
- 3、初始化
Vue.options
对象,并给其初始化了components
、directives
、filters
- 4、初始化
keep-alive
内置组件 - 5、注册了
Vue.use()
用来实现插件机制 - 6、注册了
Vue.mixin()
来实现混入机制 - 7、注册了
Vue.extend()
来实现基于传入的options
返回一个组件的构造函数 - 8、注册了
Vue.directive()
、Vue.component()
、Vue.filter()
来存放全局指令、组件、过滤器
我们在下图所示位置打上断点
src/core/instance/index.js
这个文件定义了
Vue
的构造函数,然后调用各种mixin
给Vue
的原型上混入各种实例成员,我们也简要概括下:
-
1、
initMixin(Vue)
给Vue
的原型上增加_init()
-
2、
stateMixin(Vue)
给Vue
的原型上增加我们常用的一些属性和方法$data/$props/$set/$delete/$watch
-
3、
eventsMixin(Vue)
给Vue
的原型上增加事件相关方法$on/$once/$off/$emit
-
4、
lifecycleMixin(Vue)
给Vue
的原型上增加生命周期相关的方法_update/$forceUpdate/$destroy
-
5、
renderMixin(Vue)
给Vue
的原型上挂载了$nextTick/_render
同样的,我们在下图所示位置打上断点
src/platforms/web/runtime/index.js
前两个文件都是处理和平台无关的核心代码,这个文件中处理了一些和平台相关的逻辑。(平台指浏览器平台(
web
目录)和 weex 平台(weex
目录))
-
1、这个文件中处理了
Vue.config
默认配置中的一些东西 -
2、然后注册了和平台相关的全局指令(
v-model
、v-show
)和全局组件(transition
、transition-group
) -
3、往原型上挂载了
__patch__
和$mount
方法__patch__
:把虚拟 DOM 转换成真实 DOM- 而
$mount
就是挂载方法了
同样的,我们在下图所示位置打上断点
src/platforms/web/entry-runtime-with-compiler.js
这个文件是 Vue 打包时的入口文件,它打包的是完整版的 Vue ,即运行时和编译器都有。它里面主要做了下面这些事:
- 1、重写了
Vue
原型上的 $mount 方法,增加了把模板编译成render
函数的功能 - 2、给
Vue
的构造函数增加了一个Vue.complier()
方法,给开发者手动调用把模板编译成render
函数
同样的,我们在下图所示位置打上断点
嘉陵关决战
做完上面这一堆起手式,高低得干一架了吧。按 command + r 刷新页面进入断点
刷新完页面后,应该会和我一样进入到下图所示吧(进入的是src/core/instance/index.js
文件中的断点位置)
动手
先在右边那个
watch
面板添加Vue
构造函数的监听,算了,我还是给个图吧。
从上图可以看到现在的 Vue
构造函数上面只有一些默认的成员,我们接下来就会看到往它上面挂载成员的详细过程。我们按 F10 或者下图中的那个图标跳过 initMixin(Vue)
的执行过程,在右边的 watch
面板就能实时观测到 Vue
构造函数上面比刚开始多了一个 _init()
方法。
这里就不执行一个函数贴一张图了,大家可以对着自己看看,没看清楚可以重新刷新页面来几次。然后就要进入下一个文件调试了朋友们😁,按 F8 或者下图中的那个图标跳到下一个断点。从下图中就能看到经过上一个文件(src/core/instance/index.js
)中的操作后, Vue
构造函数原型上面多出来一大堆东西,当然有我们熟悉的“朋友”,也有陌生的“朋友”。
迄今所有人生都大写着失败,但不妨碍我们继续向前——狂铁
点击下图中的小箭头或者按 F11 进入到 initGlobalAPI()
方法中,然后就可以自己按 F10 一步一步跳过里面的函数同时观察右边 Watch 面板中 Vue 构造函数的变化情况了。每个文件中主要做的工作也都在上一小节粮草先行中写了,有需要可以回看下。
重复的操作我们就不走了,大家都是聪明的程序员,接下来的就交给你们自己吧。F8 跳到下一个断点,F10 跳过函数的执行,F11 进入函数。
重复 debug
几次,应该就能对 Vue
初始化实例成员和静态成员的过程观察的非常清楚了。小子才疏学浅,有任何问题欢迎评论区留言哦。
下一次相遇
要是有下一篇,应该就是关于 Vue
首次渲染的详细 debug 过程了。
努力生活是头等大事,祝朋友们岁月静好。