Skip to content
On this page

new Vue到底都干了啥呢?🙄

很多时候我们都会被问到new Vue到底发生了肾么事?这篇文章我们就来好好的看看!!!😁

首先我们从源码调试开始

之前有一篇文章提到了vue源码调试,可以移步至此。

入口文件

当执行run dev时,我们可以根据package.json中配置拿到相应的参数

"dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",

此时我们可以拿到一个路径scripts/config.js 和参数TARGET:web-full-dev

scripts/config.js文件中可以看到定义的builds对象找到web-full-dev对应的属性值 这时找到了入口文件src\platforms\web\entry-runtime-with-compiler.js

入口文件干了啥?

从上面的代码可以看出拓展了$mount,接着就是根据传入的参数el获取dom元素。然后判断有没有render,如果没有render则去找template,如果没有template则根据函数getOuterHTMLel内部内容作为template,所以我们可以得出结论,render template el的优先级是 render > template > el。如果template 则需要函数compileToFunctionstemplate编译得到一个render函数,并把render设置到组件选项上。最后执行了mount方法的默认任务。

接下来正式进入主题

寻找构造函数Vue

在入口文件中可以看到从./runtime/index文件导入Vue,进入此文件。 可以看到core/index文件中导入的Vue,还可以看到实现了$mount方法。

进入文件core/index可以看到从./instance/index中导入了Vue,而且执行了一个全局Api初始化方法initGlobalAPI,继续进入./instance/index终于找到了Vue构造函数。在Vue构造函数中执行了_init方法。下面也执行了一系列的混入。可以在initMixin中找到_init方法。下面我们来看看_init方法到底干了什么。

构造函数中的_init干了啥?

这里我们可以很清楚的看到这一系列的流程。属性的合并接着是各种初始化。

  • initLifecycle -> 定义了 $parent$children$root$ref
  • initEvent -> 对于一些自定义事件的监听
  • initRender -> 定义了$slots$createElement, 让$attrs $listeners变成响应式的
  • 执行生命周期beforeCreate
  • initInjections -> 获取祖辈注入的数据
  • initState -> 数据初始化:datapropsmethodscomputedwatch
  • initProvide -> 将数据提供给后代
  • 执行生命周期created
  • 执行挂载

如何挂载

回到刚刚提到的实现了$mount方法的文件core/index这里返回了一个从文件core/instance/lifecycle函数mountComponent在执行这个函数之前首先是执行的是我们拓展的$mount函数,在那里可以拿到render。在mountComponent中执行了beforeMount钩子,然后new Watcher执行updateComponent函数。这个函数主要做的事情就是通过_render()函数把render变成虚拟dom,通过_update把虚拟dom变成真实dom插入到试图中,最后执行mount钩子函数

总结

以上大概就是我理解的new Vue干了一系列的操作,如有需要改进的地方,欢迎留言哦~~~最后来个思维导图

掘金