Vue3源码解读--方向篇

简介: 本文适合对vue3源码感兴趣,或者想学习vue3源码的小伙伴阅读。

一、前言


vue3文档地址、GitHub项目地址:

https://cn.vuejs.org/v2/api/

https://github1s.com/vuejs/vue-next/tree/3.2

 

最近有小伙伴私聊广东靓仔,想系统的看vue3的源码,vue作为他主要的技术栈,想深入学习vue3,但是vue3太大了,无从下手。

image.png

   广东靓仔接下来会写几期直白的Vue3源码的文章~


二、如何本地调试vue3源码


   很多时候我们都是在本地调试vue3的源码,然后沿着调用链,一步一步的去梳理vue3的源码。


   把vue3项目拉到我们本地后,找到rollup.config.js文件,如下图所示:

image.png


然后在第85行开启sourcemap配置开启,

image.png


Source map是啥

简单理解:

Source map就是一个信息文件,里面储存着位置信息。转换后的代码的每一个位置,所对应的转换前的位置。


有了Source map,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,这样调试起来就会非常方便。


然后在你想调试的地方增加debugger即可


三、vue3有哪些不同


静态类型检查

我们都知道vue2是使用了Flow。


Flow是啥?

   Flow 是 Facebook 推出的,作为JavaScript 静态类型检查工具,它以非常小的成本对已有的 JavaScript 代码迁入,非常灵活。But对于一些复杂场景类型的检查,支持得并不好。在vue2中,我们有时候看到过一些any有人就吐槽了。


Vue3 没用 Flow ,而是采用 TypeScript 重构了整个项目。


Why?

   TypeScript提供了更好的类型检查,它能支持复杂的类型推导;

 

源码使用 TypeScript 编写,不再需要去单独维护 d.ts 文件,而且就整个 TypeScript 的生态来看,TypeScript 团队也是越做越好,TypeScript 本身保持着一定频率的迭代和更新,支持的 feature 也越来越多。


代码管理

Vue2 源码都是在src 目录下,如下图所示:

image.png

红色框住的:compiler、core、platforms、server、sfc、shared目录:

  • compiler:模板编译的相关代码
  • core:与平台无关的通用运行时代码
  • platforms:平台专有代码
  • server:服务端渲染的相关代码
  • sfc:.vue 单文件解析相关代码
  • shared: 共享工具代码


monorepo

Vue3 是通过 monorepo 的方式来维护,目录如下图所示:

image.png

   

我们可以看到packages文件中放了功能不同的模块。下面我们拿其中compiler-core展开来看,如下图所示:

image.png


每个 package都有各自的 API、类型定义和测试。


Why?

广东靓仔认为是这样的:把每个模块拆分更细,那么它们之间的职责划分更明确,模块之间的依赖也更加清楚,方便我们阅读、理解和调试代码,很明显这样做是可以提高代码的可维护性。


还有更重要的一点,如果我们只是想使用这些包中的某一个,我们可以单独安装,而不需要安装整个vue。


Composition API


Vue3.0 提供了 Composition API,可以看到在语法进行了优化。

优化逻辑组织

将某个逻辑相关的代码全都放在一个函数里,这样就一目了然,看代码的时候我们就不需要切换目录。


逻辑复用

vue2使用mixins达到代码复用,用的人爽,后面维护的人,心里估计已经在拔刀了。
vue3我们可以用hook 函数,然后引入调用即可。


性能优化

vue3打包优化

  使用 tree-shaking 的技术,减少打包体积。Tree-shaking的本质是消除无用的js代码,也就是说我们在开发的时候不引入这个模块的所有代码,只引入需要的代码,打包后,只会包含我们引入的。    


tree-shaking 依赖 ES2015 模块语法的静态结构(即 import export),通过编译阶段的静态分析,找到没有引入的模块并打上标记。Tips:如果项目使用了 Transition、KeepAlive 等组件,也会被打包的~


优化编译过程

挂载过程,如下图:

image.png


编译过程,如下图:

image.png


   我们知道在数据劫持以及patch可以优化的地方比较多,vue3在编译阶段对静态模板的分析,编译生成了 Block tree。基于动态节点指令切割,每个区块内部的节点结构是固定的,以一个 Array 来追踪自身包含的动态节点。


Vue 将 vnode 更新性能与动态内容的数量相关,很大程度提升性能。   Vue 3.在编译阶段还对 Slot 的编译进行了优化、事件侦听函数做了缓存优化,运行时重写了 diff 算法...等等


new Proxy    

   vue2数据劫持需要提前定义好key,vue3中使用Proxy,通过劫持整个对象 ,Object.defineProperty做不到的,它都可以实现了。vue3在getter 中递归找到真正的内部对象然后做响应式。这也是性能提升的一个环节。


四、分模块梳理源码


vue3挺大的一个项目,我们可以分模块来梳理:

  • provide inject
  • 自定义事件
  • VNode
  • 动态组件
  • 双向绑定原理new Proxy
  • reactive源码

......等等


五、总结


   在我们阅读完官方文档后,我们一定会进行更深层次的学习,比如看下框架底层是如何运行的,以及源码的阅读。  


这里广东靓仔给下一些小建议:

  • 在看源码前,我们先去官方文档复习下框架设计理念、源码分层设计
  • 阅读下框架官方开发人员写的相关文章
  • 借助框架的调用栈来进行源码的阅读,通过这个执行流程,我们就完整的对源码进行了一个初步的了解
  • 接下来再对源码执行过程中涉及的所有函数逻辑梳理一遍
相关文章
|
8天前
|
JavaScript
Vue3中路由跳转的语法
Vue3中路由跳转的语法
111 58
|
1天前
|
存储 API
vue3中如何动态自定义创建组件并挂载
vue3中如何动态自定义创建组件并挂载
|
6天前
|
JavaScript 索引
Vue 2和Vue 3的区别以及实现原理
Vue 2 的响应式系统通过Object.defineProperty来实现,它为对象的每个属性添加 getter 和 setter,以便追踪依赖并响应数据变化。
22 9
|
8天前
|
JavaScript 开发工具
vite如何打包vue3插件为JSSDK
【9月更文挑战第10天】以下是使用 Vite 打包 Vue 3 插件为 JS SDK 的步骤:首先通过 `npm init vite-plugin-sdk --template vue` 创建 Vue 3 项目并进入项目目录 `cd vite-plugin-sdk`。接着,在 `src` 目录下创建插件文件(如 `myPlugin.js`),并在 `main.js` 中引入和使用该插件。然后,修改 `vite.config.js` 文件以配置打包选项。最后,运行 `npm run build` 进行打包,生成的 `my-plugin-sdk.js` 即为 JS SDK,可在其他项目中引入使用。
|
6天前
|
JavaScript 调度
Vue3 使用 Event Bus
Vue3 使用 Event Bus
11 1
|
6天前
|
JavaScript
Vue3 : ref 与 reactive
Vue3 : ref 与 reactive
9 1
vue3 reactive数据更新,视图不更新问题
vue3 reactive数据更新,视图不更新问题
|
7天前
|
JavaScript
|
7天前
vue3定义暴露一些常量
vue3定义暴露一些常量
|
6天前
Vue3 使用mapState
Vue3 使用mapState
10 0