前段时间尤大(Evan You,尤雨溪)又双叒叕发朋友圈了,Vue 3.4 beta(公测版)将于本周正式发布,且期望在今年年底尘埃落定。
所以,本期共享的是尤大亲笔的官方博客,Vue 团队官宣 Vue 3.3 正式发布,一起来重温今年五月 Vue 3.3 的升级大纲,为 Vue 3.4 预热前戏。
免责声明
本文属于是语冰的直男翻译了属于是,仅供粉丝参考,英文原味版请临幸 Announcing Vue 3.3。
今天,我们十分鸡冻,普大喜奔 —— Vue 3.3(代号“浪客剑心”)正式发布!
此版本聚焦于优化 UX(开发体验) —— 尤其是 SFC(单文件组件)<script setup>
和 TS(TypeScript)梦幻联动。联手Vue 语言工具(曾用名 Volar) 的 1.6 版本,我们搞定了一大坨用 TS 写 Vue 的痼疾。
本文概述了 Vue 3.3 的亮点功能。关于更新的完整清单,请传送 GitHub 完整更新日志。
依赖更新
当升级到 Vue 3.3 时,建议同时更新以下依赖:
-
volar/vue-tsc@^1.6.4
-
vite@^4.3.5
-
@vitejs/plugin-vue@^4.2.0
-
vue-loader@^17.1.0
(如果使用了 webpack/vue-cli)
Vue 3.3 版本速览:
- 优化
<script setup>
+ TS DX(开发体验)-
支持宏中的导入类型和复杂类型
-
泛型组件
-
更符合人体工程学的
definedEmits
-
携带
definedSlots
的类型插槽
-
- 实验性功能
-
响应式
props
解构 -
defineModel
-
- 其他重要功能
-
defineOptions
-
更好地支持
getter
与toRef
和toValue
一起使用 -
支持 JSX 导入源
-
-
优化维护基建
优化 <script setup>
+ TS DX
支持宏中的导入类型和复杂类型
以前,defineProps
和 defineEmits
类型参数位置中使用的类型仅限于局部类型,并且能且仅能支持类型字面量和接口。这是因为,Vue 需要分析 props
接口上的属性,生成相应的运行时选项。
此限制现已被 Vue 3.3 解决。编译器现在可以解析导入类型,并支持一组有限的复杂类型:
请注意,复杂类型支持基于 AST,因此无法 100% 全面支持。某些需要实际类型分析的复杂类型,比如支持条件类型,并无法支持。您可以对单个 props
的类型使用条件类型,但不能对整个 props
对象使用。
泛型组件
使用了 <script setup>
的组件现在可以通过 generic
属性接受泛型类型参数:
generic
的值与 TS 中 <...>
之间的参数列表完全相同。举个栗子,您可以使用多个参数、extends 约束
、默认类型和引用导入类型:
此功能以前需要显式选用,但现在最新版本的 volar/vue-tsc
默认启用。
更符合人体工程学的 definedEmits
以前,defineEmits
的类型参数能且仅能支持调用签名语法:
const emit = defineEmits<{
(e: 'foo', id: number): void
(e: 'bar', name: string, ...rest: any[]): void
}>()
该类型匹配 emit
的返回类型,但有点冗长且难以编写。Vue 3.3 引入了一种更符合人体工程学的 emits
类型声明方式:
const emit = defineEmits<{
foo: [id: number]
bar: [name: string, ...rest: any[]]
}>()
在类型字面量中,键是事件名称,值是指定额外参数的数组类型。尽管这不是必需的,但您可以使用标签元组元素来明确,如上所示。
调用签名语法仍然支持。
携带 definedSlots
的类型插槽
新的 defineSlots
宏可用于声明预期插槽及其各自的预期插槽 props
:
defineSlots()
能且仅能接受类型参数,而不是运行时参数。类型参数应该是类型字面量,其中属性键是插槽名,值是插槽函数。函数的首参是插槽期望接收的 props
,其类型将用于模板中的插槽 props
。defineSlots
的返回值与 useSlots
返回的插槽对象相同。
目前的某些限制:
-
volar/vue-tsc
中尚未实现所需的插槽检查。 -
插槽函数返回类型目前被忽略,且可以是
any
,但我们将来可能会利用它来检查插槽内容。
还有一个相应的 slots
选项供 defineComponent
使用。这两个 API 都没有运行时影响,纯粹用作 IDE 和 vue-tsc
的类型提示。
实验性功能
响应式 props 解构
响应式 props
解构以前是响应性转换(现已废弃)的一部分,现已被抽离为一个单独的功能。
该功能允许解构的 props
保留响应性,并提供更符合人体工程学的方式来声明 props
默认值:
此功能是实验性的,需要显式选用。
defineModel
以前,对于支持与 v-model
双向绑定的组件,它需要 :
-
声明一个
prop
-
在打算更新该
prop
时触发相应的update:propName
事件:
Vue 3.3 通过新的 defineModel
宏简化了用法。该宏自动注册一个 prop
,并返回一个可以直接变更的 ref
:
此功能是实验性的,需要显式选用。
其他重要功能
defineOptions
新的 defineOptions
宏允许直接在 <script setup>
中声明组件选项,而不需要单独的 <script>
块:
更好地支持 getter
与 toRef
和 toValue
一起使用
toRef
已增强,支持将值/getter
/现有 ref
标准化为 ref
:
toRef(1)
toRef(() => props.foo)
toRef(existingRef)
使用 getter
调用 toRef
与 computed
类似,但当 getter
仅执行属性访问而不进行昂贵的计算时,效率会更高。
新的 toValue
工具方法提供了相反的功能,将值/getter
/ref
标准化为值:
toValue(1)
toValue(ref(1))
toValue(() => 1)
toValue
可以在组合式函数中代替 unref
,以便您的组合式函数可以接受 getter
作为响应式数据源:
useFeature(computed(() => props.foo))
useFeature(toRef(props, 'foo'))
useFeature(() => props.foo)
toRef
和 toValue
之间的关系类似于 ref
和 unref
之间的关系,主要区别在于 getter
函数的特殊处理。
支持 JSX 导入源
目前,Vue 的类型自动注册全局 JSX 类型。这可能与其他需要 JSX 类型推断的库“梦幻联动”时产生冲突,尤其是 React。
从 Vue 3.3 开始,Vue 支持通过 TS 的 jsxImportSource
选项指定 JSX 命名空间。这允许用户根据其用例选择全局或每个文件选用。
为了向后兼容,Vue 3.3 仍然全局注册 JSX 命名空间。我们计划在 Vue 3.4 中移除默认的全局注册。如果您让 TSX 与 Vue “梦幻联动”,那么应在升级到 Vue 3.3 后将显式 jsxImportSource
添加到 tsconfig.json
中,避免在 Vue 3.4 中爆炸。
优化维护基建
此版本建立在一大坨维护基建优化的基础上,使我们能够昂首先前:
-
通过将类型检查与 rollup 构建分开并从
rollup-plugin-typescript2
迁移到rollup-plugin-esbuild
,构建速度提高了 10 倍。 -
从 Jest 迁移到 Vitest,测试速度更快。
-
从
@microsoft/api-extractor
迁移到rollup-plugin-dts
,更快地生成类型。 -
通过 ecosystem-ci 进行综合回归测试 —— 在发布前捕获主要生态系统依赖的回归!
依计行事,我们的目标是在今年开始发布更小、更频繁的功能版本。敬请期待!