从 vue 源码看问题 —— vue 初始化都做了什么事?

简介: 从 vue 源码看问题 —— vue 初始化都做了什么事?

image.png

前言

最近想要对 Vue2 源码进行学习,主要目的就是为了后面在学习 Vue3 源码时,可以有一个更好的对比和理解,所以这个系列暂时不会涉及到 Vue3 的内容,但是 Vue3 的核心模块和 Vue2 是一致的,只是在实现上改变了方式、进行了优化等。

准备工作

再开始阅读源码之前,有些事还是必须要做的,那就是拉取 源仓库代码 或者直接下载 ZIP 格式文件,处理好之后就需要打开神器 VScode

打开编辑器之后,你需要做的就是:

  • 安装依赖 install ——  yarn 或者 npm
  • 找到 package.json 文件并找到里面的 scripts 部分,然后往 dev 命令中加入 --sourcemap 配置参数,或者新建建一个 dev:sourcemap 命令,其内容就是比 dev 命令多了个 --sourcemap 配置,其实主要就是为了生成 vue.js.map 文件方便后面调试
  • image.png
  • 执行 npm run dev:sourcemap 命令,执行成功以后就会在 dist 目录下生成 vue.js.map 文件

image.png

  • 然后就可以在 example 目录下,写一些自己想要测试的例子,然后通过 debug 的形式找到对应内容在代码中的位置

image.png

深入源码

Vue 初始化的代码位置

既然要深入了解 Vue 初始化的内容,那么我们就得先找到 Vue 初始化是在哪里进行的,那么查找的方式有两种:

  • 通过 package.json 文件来进行查找 —— 在 script 脚本命令配置中有 "dev": "rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev",其中的 scripts/config.jsTARGET:web-full-dev 就为指明了文件里的具体配置,然后可以在逐层查找对应的入口文件
  • 通过 debug 模式进行查找 —— 首先在 example 目录下新建一个目录,可以是任何名字,本文讨论的是初始化的内容,这里就将其命名为 init,在 init 目录下新建一个 html 文件,在里面引入 dist 目录下的 vue.js, 因为生成的 map 文件是 vue.js.map,否则 debug 时不方便查找对应的文件位置
  • image.png

这里选择方式二,毕竟方式一通过 rollup 配置查找还是过于繁琐,于是通过 debug 可以快速确定 Vue 进行初始化的文件位置.

image.png

this._init(options) 初始化

src>core>index.js 文件中,可以清晰的看到,在我们进行 new Vue() 时,调用的其实就是 this._init() 方法,而这个方法又是在 initMixin(Vue) 中进行定义的

image.png

initMixin(Vue) 方法

src>core>init.js 文件中,可以看到在 initMixin() 方法中最核心的就是处理组件配置项的部分,这一部分又分为 子组件根组件 的配置,又分别对应 initInternalComponent() 方法 和 mergeOptions()方法 + resolveConstructorOptions()方法.

image.png

同时,在 Vue.prototype._init 函数中还存在下面的这些方法的调用,后面会依次对每个方法进行解读:

image.png

子组件 —— initInternalComponent() 方法

这个方法做的事就是创建 $options 对象,然后对组件选项进行打平做性能优化,因为组件有很多的配置,其中也会存在各种嵌套的配置,在访问时免不了要通过原型链进行动态查找,会影响执行效率.

  • 根据 vm 的构造函数创建新的配置对象,即平时访问的 $options 对象
  • 把当前组件配置项打平然后赋值到 $options 对象,避免了原型链的动态查找
  • 如果当前组件配置项中存在 render 选项,就把它添加到 $options 对象上
  • image.png

根组件 —— resolveConstructorOptions() 方法

src>core>init.js 文件中,resolveConstructorOptions() 方法其实最主要的事情就是从构造函数上解析配置对象,具体如下:

  • 如果构造函数的 super 属性存在,证明还有基类,此时需要递归进行对配置选项解析
  • 将构造函数的基类配置项进行缓存,然后比对当前配置项配置项进行对比,如果不一致,则表明基类的配置项已发生更改
  • 找出被更改的配置项和 extent 选项进行合并,并赋值给 $options

image.png

根组件 —— mergeOptions() 方法

src>core>options.js 文件中,mergeOptions() 方法主要做的事情就是:

  • 对配置选项进行标准化
  • 对传入的原始配置对象进行合并
  • 返回新的配置对象 根组件合并配置项,就是将全局配置项合并到根组件局部配置项中,比如将全局注册的 Vue.componet(options) 全局配置合并到根组件 new Vue(options) 上得到类似:
new Vue({
     el: xxx,
     data: { xxx },
     componets:{
       localComponents,
       globalComponents,
     }
   })
复制代码

image.png

initLifecycle() 方法

src>core>init.js 文件中调用 initLifecycle()方法,方法的具体定义位置为src>core>lifecycle.js.

可能很多人会误以为该方法是初始化生命周期钩子函数的(因为其方法名),其实这个方法主要是对组件关系属性进行初始化,比如:$root、$parent、$children、$refs 等.

image.png

目录
相关文章
|
1天前
|
JavaScript
vue页面加载时同时请求两个接口
vue页面加载时同时请求两个接口
|
1天前
|
JavaScript
vue里样式不起作用的方法,可以通过deep穿透的方式
vue里样式不起作用的方法,可以通过deep穿透的方式
14 0
|
1天前
|
移动开发 JavaScript 应用服务中间件
vue打包部署问题
Vue项目`vue.config.js`中,`publicPath`设定为"/h5/party/pc/",在线环境基于打包后的`dist`目录,而非Linux的`/root`。Nginx代理配置位于`/usr/local/nginx/nginx-1.13.7/conf`,包含两个相关配置图。
vue打包部署问题
|
1天前
|
JavaScript 前端开发
iconfont 图标在vue里的使用
iconfont 图标在vue里的使用
17 0
|
1天前
|
JavaScript
vue打印v-model 的值
vue打印v-model 的值
|
1天前
|
JavaScript
Vue实战-组件通信
Vue实战-组件通信
7 0
|
1天前
|
JavaScript
Vue实战-将通用组件注册为全局组件
Vue实战-将通用组件注册为全局组件
7 0
|
1天前
|
JavaScript 前端开发
vue的论坛管理模块-文章评论02
vue的论坛管理模块-文章评论02
|
1天前
|
JavaScript Java
vue的论坛管理模块-文章查看-01
vue的论坛管理模块-文章查看-01
|
1天前
|
资源调度 JavaScript 前端开发
vue 项目运行过程中出现错误的问题解决
vue 项目运行过程中出现错误的问题解决
13 1