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 相关文章推荐
JavaScript 布尔操作符解析  && || !
Aug 10 Javascript
js改变img标签的src属性在IE下没反应的解决方法
Jul 23 Javascript
常见表单重复提交问题整理及解决方法
Nov 13 Javascript
javascript中数组的concat()方法使用介绍
Dec 18 Javascript
javascript获取web应用根目录的方法
Feb 12 Javascript
js分页代码分享
Apr 28 Javascript
Javascript动态引用CSS文件的2种方法介绍
Jun 06 Javascript
Javascript中replace()小结
Sep 30 Javascript
通过npm引用的vue组件使用详解
Mar 02 Javascript
前端主流框架vue学习笔记第二篇
Jul 26 Javascript
详解Vue源码学习之双向绑定
Apr 10 Javascript
jquery将json转为数据字典的实例代码
Oct 11 jQuery
基于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
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
jQuery ajax 路由和过滤器使用说明
2011/08/02 Javascript
javascript字符串循环匹配实例分析
2015/07/17 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
jQuery添加和删除输入文本框标签代码
2016/05/20 Javascript
JavaScript中setter和getter方法介绍
2016/07/11 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
解决前端跨域问题方案汇总
2016/11/20 Javascript
javascript按钮禁用和启用的效果实例代码
2017/10/29 Javascript
利用three.js画一个3D立体的正方体示例代码
2017/11/19 Javascript
JS实现简单的浮动碰撞效果示例
2017/12/28 Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
2020/01/08 Javascript
Python使用Flask框架同时上传多个文件的方法
2015/03/21 Python
python在指定目录下查找gif文件的方法
2015/05/04 Python
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
python: 判断tuple、list、dict是否为空的方法
2018/10/22 Python
详解numpy的argmax的具体使用
2019/05/27 Python
在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法
2019/06/18 Python
Python用Jira库来操作Jira
2020/12/28 Python
CSS3 Columns分列式布局方法简介
2014/05/03 HTML / CSS
英国女性运动服品牌:Sweaty Betty
2018/11/08 全球购物
YII2 全局异常处理深入讲解
2021/03/24 PHP
统计学专业毕业生的自我评价分享
2013/11/28 职场文书
计算机软件个人的自荐信范文
2013/12/01 职场文书
酒店总经理工作职责
2013/12/13 职场文书
社会实践活动总结报告
2014/04/29 职场文书
文明社区申报材料
2014/08/21 职场文书
2015年度优秀员工自荐书
2015/03/06 职场文书
个人求职意向书
2015/05/11 职场文书
机关工会工作总结2015
2015/05/26 职场文书
2015年教务主任工作总结
2015/07/22 职场文书
关爱留守儿童主题班会
2015/08/13 职场文书
学校2016年九九重阳节活动总结
2016/04/01 职场文书
使用redis生成唯一编号及原理示例详解
2021/09/15 Redis
python自动化测试之Selenium详解
2022/03/13 Python