从 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

目录
相关文章
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
3天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
3天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
3天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
2天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
4天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
2天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
17天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
4天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
9天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发