Vue3 源码导读(推荐)


Posted in Javascript onOctober 14, 2019

5号凌晨,尤雨溪公布了 Vue 3 源代码。

Vue3 源码导读(推荐)

话不多说,我们趁热对 Vue 3 源码进行一些简要的分析。

如果你还没有阅读过Composition API RFC,可能无法完全看懂下面的内容。

兼容性

目前打包后的代码是 ES2015+,不支持 IE 11。

对 TypeScript 的使用

目前的代码 98% 以上使用 TypeScript 编写。

如果你还没有学习 TypeScript,请尽快学习,否则可能看不懂源码。

另外有件事情说出来可能会让你非常惊讶,Vue 3 的源代码完全没有使用 class 关键字!(只在测试代码和示例代码里用到了 class 关键字)

什么时候发正式版

目前 Vue 3 处于 Pre-Alpha 版本。后面应该还会有 Alpha、Beta 等版本。

根据 Vue 官方时间表,至少要等到 2020 年第一季度才有可能发布 3.0 正式版。

阅读建议

强烈推荐大家用国庆假期这段时间把 Vue 3 的源码通看一遍,因为目前的代码结构清晰,而且代码量相对较少。

下载代码后,使用 yarn dev 命令就可以对其进行调试。(有人给出了详细的调试技巧)

关于阅读顺序,我的建议是

  1. 先读 reactivity,能最快了解 Vue 3 的新特性;
  2. 再读 rumtime,理解组件和生命周期的实现;
  3. 如果还有时间再读 compiler,理解编译优化过程。

另外如果你想省时间,可以直接看所有 __tests__ 目录里的测试用例来了解 Vue 3 的所有功能。目前有不到 700 个测试用例。

代码结构

代码仓库中有个 packages 目录,里面是 Vue 3 的主要功能的实现,包括

  • reactivity 目录:数据响应式系统,这是一个单独的系统,可以与任何框架配合使用。
  • runtime-core 目录:与平台无关的运行时。其实现的功能有虚拟 DOM 渲染器、Vue 组件和 Vue 的各种API,我们可以利用这个 runtime 实现针对某个具体平台的高阶 runtime,比如自定义渲染器。
  • runtime-dom 目录: 针对浏览器的 runtime。其功能包括处理原生 DOM API、DOM 事件和 DOM 属性等。
  • runtime-test 目录: 一个专门为了测试而写的轻量级 runtime。由于这个 rumtime 「渲染」出的 DOM 树其实是一个 JS 对象,所以这个 runtime 可以用在所有 JS 环境里。你可以用它来测试渲染是否正确。它还可以用于序列化 DOM、触发 DOM 事件,以及记录某次更新中的 DOM 操作。
  • server-renderer 目录: 用于 SSR。尚未实现。
  • compiler-core 目录: 平台无关的编译器. 它既包含可扩展的基础功能,也包含所有平台无关的插件。
  • compiler-dom 目录: 针对浏览器而写的编译器。
  • shared 目录: 没有暴露任何 API,主要包含了一些平台无关的内部帮助方法。
  • vue 目录: 用于构建「完整构建」版本,引用了上面提到的 runtime 和 compiler。

可以看出,新的 Vue 代码仓库是模块化的。接下来我们逐一来看看每个模块暴露的 API。

@vue/runtime-core 模块

大部分 Vue 开发者应该不会用到这个模块,因为它是专门用于自定义 renderer 的。

使用方法示例:

import { createRenderer, createAppAPI } from '@vue/runtime-core'

const { render, createApp } = createRenderer({
 pathcProp,
 insert,
 remove,
 createElement,
 // ...
})

// `render` 是底层 API
// `createApp` 会产生一个 app 实例,该实例拥有全局的可配置上下文
export { render, createApp }

export * from '@vue/runtime-core'

@vue/runtime-dom 模块

这个模块是基于上面模块而写的浏览器上的 runtime,主要功能是适配了浏览器环境下节点和节点属性的增删改查。它暴露了两个重要 API:render 和 createApp,并声明了一个 ComponentPublicInstance 接口。

export { render, createApp }

// re-export everything from core
// h, Component, reactivity API, nextTick, flags & types
export * from '@vue/runtime-core'

export interface ComponentPublicInstance {
 $el: Element
}

@vue/runtime-test 模块

这个模块的主要功能是用对象来表示 DOM 树,方便测试。并且提供了很多有用的 API 方便测试:

export { render, createApp }

// convenience for one-off render validations
export function renderToString(vnode: VNode) {
 const root = nodeOps.createElement('div')
 render(vnode, root)
 return serializeInner(root)
}

export * from './triggerEvent'
export * from './serialize'
export * from './nodeOps'
export * from './jestUtils'
export * from '@vue/runtime-core'

@vue/reactivity 模块

这是一个极其重要的模块,它是一个数据响应式系统。其暴露的主要 API 有 ref(数据容器)、reactive(基于 Proxy 实现的响应式数据)、computed(计算数据)、effect(副作用) 等几部分:

export { ref, isRef, toRefs, Ref, UnwrapRef } from './ref'
export {
 reactive,
 isReactive,
 readonly,
 isReadonly,
 toRaw,
 markReadonly,
 markNonReactive
} from './reactive'
export {
 computed,
 ComputedRef,
 WritableComputedRef,
 WritableComputedOptions
} from './computed'
export {
 effect,
 stop,
 pauseTracking,
 resumeTracking,
 ITERATE_KEY,
 ReactiveEffect,
 ReactiveEffectOptions,
 DebuggerEvent
} from './effect'
export { lock, unlock } from './lock'
export { OperationTypes } from './operations'

很明显,这个模块就是 Composition API 的核心了,其中的 ref 和 reactive 应该重点掌握。

@vue/compiler-core 模块

这个编译器的暴露了 AST 和 baseCompile 相关的 API,它能把一个字符串变成一棵 AST。

export function baseCompile(
 template: string | RootNode,
 options: CompilerOptions = {}
): CodegenResult {
 // 详情略 ...
 return generate(ast, options)
}

export { parse, ParserOptions, TextModes } from './parse'
export { transform /* ... */ } from './transform'
export { generate, CodegenOptions, CodegenContext, CodegenResult} from './codegen'
export { ErrorCodes, CompilerError, createCompilerError } from './errors'
export * from './ast'

@vue/compiler-dom 模块

这个模块则基于上个模块,针对浏览器做了适配,如对 textarea 和 style 标签做了特殊处理。

@vue/server-renderer 模块

目前这个模块没有实现任何功能。

vue 模块

这个模块就是简单的引入了 runtime 和 compiler:

import { compile, CompilerOptions } from '@vue/compiler-dom'
import { registerRuntimeCompiler, RenderFunction } from '@vue/runtime-dom'

function compileToFunction(
 template: string,
 options?: CompilerOptions
): RenderFunction {
 const { code } = compile(template, {
  hoistStatic: true,
  ...options
 })
 return new Function(code)() as RenderFunction
}

registerRuntimeCompiler(compileToFunction)

export { compileToFunction as compile }
export * from '@vue/runtime-dom'

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Extjs入门之动态加载树代码
Apr 09 Javascript
在vs2010中调试javascript代码方法
Feb 11 Javascript
jquery ajax 调用失败的原因示例介绍
Sep 27 Javascript
jquery数组之存放checkbox全选值示例代码
Dec 20 Javascript
JS是按值传递还是按引用传递
Jan 30 Javascript
jquery实现下拉框功能效果【实例代码】
May 06 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
bootstrap组件之按钮式下拉菜单小结
Jan 19 Javascript
Vue.js在使用中的一些注意知识点
Apr 29 Javascript
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
Jun 01 Javascript
jQuery中DOM常见操作实例小结
Aug 01 jQuery
Javascript模块化机制实现原理详解
Apr 02 Javascript
基于JS实现父组件的请求服务过程解析
Oct 14 #Javascript
JavaScript this在函数中的指向及实例详解
Oct 14 #Javascript
vue循环数组改变点击文字的颜色
Oct 14 #Javascript
基于纯JS实现多张图片的懒加载Lazy过程解析
Oct 14 #Javascript
VUE+node(express)实现前后端分离
Oct 13 #Javascript
javascript sort()对数组中的元素进行排序详解
Oct 13 #Javascript
javaScript把其它类型转换为Number类型
Oct 13 #Javascript
You might like
打造计数器DIY三步曲(中)
2006/10/09 PHP
PHP实现事件机制的方法
2015/07/10 PHP
PHP面向对象程序设计之多态性的应用示例
2018/12/19 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
JQuery 常用方法和事件详细介绍
2013/04/18 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
Array 重排序方法和操作方法的简单实例
2014/01/24 Javascript
Nodejs极简入门教程(一):模块机制
2014/10/25 NodeJs
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
javascript元素动态创建实现方法
2015/05/13 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
微信开发之调起摄像头、本地展示图片、上传下载图片实例
2016/12/08 Javascript
JS中from 表单序列化提交的代码
2017/01/20 Javascript
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
微信小程序语音同步智能识别的实现案例代码解析
2020/05/29 Javascript
[33:17]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
python利用beautifulSoup实现爬虫
2014/09/29 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
Windows系统下PhantomJS的安装和基本用法
2018/10/21 Python
python f-string式格式化听语音流程讲解
2019/06/18 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
2019/06/25 Python
pytorch:model.train和model.eval用法及区别详解
2020/02/20 Python
python利用xlsxwriter模块 操作 Excel
2020/10/14 Python
利用python爬取有道词典的方法
2020/12/08 Python
Python制作运行进度条的实现效果(代码运行不无聊)
2021/02/24 Python
html5 利用canvas实现超级玛丽简单动画
2013/09/06 HTML / CSS
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
2014教师年度思想工作总结
2014/11/10 职场文书
送达通知书
2015/04/25 职场文书
2016年教师党员公开承诺书
2016/03/24 职场文书
anaconda python3.8安装后降级
2021/06/11 Python