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 相关文章推荐
关于jQuery对象数据缓存Cache原理以及jQuery.data详解
Apr 07 Javascript
js和as的稳定传值问题解决
Jul 14 Javascript
Node.js实现的简易网页抓取功能示例
Dec 05 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件包装
Nov 20 Javascript
纯JS实现轮播图
Feb 22 Javascript
Jquery-data的三种用法
Apr 18 jQuery
基于JavaScript实现简单的音频播放功能
Jan 07 Javascript
vue脚手架搭建过程图解
Jun 06 Javascript
微信小程序使用自定义组件导航实现当前页面高亮
Jan 02 Javascript
vue实现学生信息管理系统
May 30 Javascript
vue中父子组件的参数传递和应用示例
Jan 04 Vue.js
js 数组 fill() 填充方法
Nov 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
DOTA2 玩家自创拉野攻略 特色英雄快速成长篇
2020/04/20 DOTA
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
对PHP新手的一些建议(PHP学习经验总结)
2014/08/20 PHP
Yii的CDbCriteria查询条件用法实例
2014/12/04 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
Yii2 assets清除缓存的方法
2016/05/16 PHP
浅谈ThinkPHP中initialize和construct的区别
2017/04/01 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
网上抓的一个特效
2007/05/11 Javascript
javascript 文章截取部分无损html显示实现代码
2010/05/04 Javascript
初识JQuery 实例一(first)
2011/03/16 Javascript
使用jQuery操作Cookies的实现代码
2011/10/09 Javascript
使用js画图之正弦曲线
2015/01/12 Javascript
jQuery实现根据类型自动显示和隐藏表单
2015/03/18 Javascript
使用 stylelint检查CSS_StyleLint
2016/04/28 Javascript
nodejs获取微信小程序带参数二维码实现代码
2017/04/12 NodeJs
react高阶组件经典应用之权限控制详解
2017/09/07 Javascript
vue 过滤器filter实例详解
2018/03/14 Javascript
Vue插槽原理与用法详解
2019/03/05 Javascript
Python 调用VC++的动态链接库(DLL)
2008/09/06 Python
Python实现根据指定端口探测服务器/模块部署的方法
2014/08/25 Python
对Python进行数据分析_关于Package的安装问题
2017/05/22 Python
Python进程间通信Queue实例解析
2018/01/25 Python
详解python中的模块及包导入
2019/08/30 Python
Python实现二叉树的最小深度的两种方法
2019/09/30 Python
python+mysql实现个人论文管理系统
2019/10/25 Python
Django正则URL匹配实现流程解析
2020/11/13 Python
python3判断IP地址的方法
2021/03/04 Python
css sprite简单实例
2016/05/23 HTML / CSS
比利时买床:Beter Bed
2017/12/06 全球购物
餐饮商业计划书范文
2014/04/29 职场文书
旅游饭店管理专业自荐书
2014/06/28 职场文书
机票销售员态度不好检讨书
2014/09/27 职场文书
2014法制宣传日活动总结范文
2014/11/01 职场文书
Pillow图像处理库安装及使用
2022/04/12 Python
LyScript实现绕过反调试保护的示例详解
2022/08/14 Python