评论

Vue 3.3 发布了,来看看有哪些更新~

原标题:Vue 3.3 发布了,来看看有哪些更新~

作者:@尤雨溪

译者:公号 — 若川视野

原文链接:

https://blog.vuejs.org/posts/vue-3-3

今天,我们很高兴地宣布发布 Vue 3.3 “浪客剑心”!

此版本专注于开发人员体验改进-特别是SFC < setup> 与Type的使用。与 Vue语言工具[1] (以前称为Volar)的1.6版本一起,我们在将Vue与Type一起使用时解决了许多长期存在的痛点。这篇文章概述了3.3中突出显示的功能。有关更改的完整列表,请参阅GitHub 上的完整更改日志[2] 。

依赖性更新升级到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)

  • \<脚本设置> + Type DX改进[3]

    • 宏中的导入和复杂类型支持[4]

    • 通用组件[5]

    • 更符合人体工程学的定义Emits[6]

    • 带有定义插槽的类型插槽[7]

  • 实验特征[8]

    • 响应式 props 解构[9]

    • 定义模型[10]

  • 其他值得注意的功能[11]

    • 定义选项[12]

    • 使用toRef和toValue提供更好的Getter支持[13]

    • JSX导入源支持[14]

  • 维护基础设施改进[15]

1 < setup> + Type DX改进 宏中的导入和复杂类型支持

以前, defineProps 和 defineEmits 的类型参数位置中使用的类型仅限于本地类型,并且仅支持类型文字和接口。这是因为Vue需要能够分析 props 接口上的属性,以便生成相应的运行时选项。这个限制现在在3.3中得到了解决。编译器现在可以解析导入的类型,并支持一组有限的复杂类型:

vue

< setup lang= "ts">

import type{ Props } from './foo'

// imported + intersection type

defineProps<Props & { extraProp?: string }>

</>

请注意,复杂类型的支持是基于AST的,因此不是100%全面的。一些需要实际类型分析的复杂类型,例如条件类型,不受支持。您可以为单个 prop 的类型使用条件类型,但不能使用整个 prop 对象。

  • 详情: PR#8083[16]

通用组件

使用 < setup> 的组件现在可以通过 generic 属性接受通用类型参数:

vue

< setup lang= "ts"generic= "T">

defineProps<{

items: T[]

selected: T

}>

< />

generic 的值与Type中 <...> 之间的参数列表完全相同。例如,您可以使用多个参数、 extends 约束、默认类型和引用导入的类型:

vue

< setup lang= "ts"generic= "T extends string | number, U extends Item">

importtype { Item } from'./types'

defineProps<{

id: T

list: U[]

}>

< />

此功能以前需要显式选择加入,但现在在最新版本的volar / vue-tsc中默认启用。

  • 讨论:RFC #436[17]

  • 相关: 通用`defineComponent`\-PR#7963[18]

更符合人体工程学 defineEmits

以前, defineEmits 的类型参数仅支持调用签名语法:

ts

// BEFORE

constemit = defineEmits<{

(e: 'foo', id: number): void

(e: 'bar', name: string, ...rest: any[]): void

}>

The type matches the return type for emit , but is a bit verbose and awkward to write. 3.3 introduces a more ergonomic way of declaring emits with types:

ts

// AFTER

constemit = defineEmits<{

foo: [id: number]

bar: [name: string, ...rest: any[]]

}>

在类型字面值中,键是事件名称,值是指定附加参数的数组类型。虽然不是必需的,但您可以使用 标记的元组元素[19] 来显式,如上例所示。仍然支持调用签名语法。

键入的插槽 defineSlots

新的 defineSlots 宏可用于声明预期插槽及其各自的预期插槽prop:

vue

< setup lang= "ts">

defineSlots<{

default?: ( props: { msg: string }) => any

item?: ( props: { id: number }) => any

}>

< />

defineSlots 只接受类型参数,不接受运行时参数。类型参数应该是类型文字,其中属性键是插槽名称,值是插槽函数。该函数的第一个参数是插槽期望接收的prop,其类型将用于模板中的插槽 prop。 defineSlots 的返回值与 useSlots 返回的插槽对象相同。目前的一些限制:

  • 所需的插槽检查尚未在volar / vue-tsc中实现。

  • 插槽函数返回类型目前被忽略,可以是 any ,但我们将来可能会利用它进行插槽内容检查。

还有一个相应的 slots 选项用于 defineComponent 使用。这两个API都没有运行时影响,纯粹作为IDE和 vue-tsc 的类型提示。

  • 详情: PR#7982[20]

2 实验特征 响应式 prop 解构

以前是现已放弃的响应性变换的一部分,响应式的解构已被拆分为一个单独的功能。该功能允许非结构化的prop保留响应性,并提供了一种更符合人体工程学的方式来声明 props 默认值:

vue

< setup>

import{ watchEffect } from'vue'

const{ msg = 'hello'} = defineProps([ 'msg'])

watchEffect( => {

// accessing `msg` in watchers and computed getters

// tracks it as a dependency, just like accessing `props.msg`

console.log( `msg is: ${msg}` )

})

< />

<template>{{ msg }}</ template>

此功能是实验性的,需要明确选择加入。

  • 详情: RFC#502[21]

defineModel

以前,为了使组件支持与 v-model 双向绑定,它需要(1)声明prop,(2)在打算更新prop时发出相应的 update:propName 事件:

vue

<!-- BEFORE -->

< setup>

constprops = defineProps([ 'modelValue'])

constemit = defineEmits([ 'update:modelValue'])

console.log(props.modelValue)

functiononInput( e) {

emit( 'update:modelValue', e.target.value)

}

</ >

< template>

< input:value= "modelValue"@ input= "onInput"/>

</ template>

3.3简化了使用新的 defineModel 宏的使用。宏会自动注册一个Props,并返回一个可以直接突变的引用:

vue

<!-- AFTER -->

< setup>

constmodelValue = defineModel

console.log(modelValue.value)

</ >

< template>

< inputv-model= "modelValue"/>

</ template>

此功能是实验性的,需要明确选择加入。

  • 详细信息:RFC #503[22]

3 其他值得注意的功能 defineOptions

新的 defineOptions 宏允许直接在 < setup> 声明组件选项,而无需单独的 <> 块:

vue

< setup>

defineOptions({ inheritAttrs: false})

< />

使用 toRef 和更好的Getter支持 toValue

toRef 已增强,以支持将值/获取器/现有引用标准化为引用:

js

// equivalent to ref(1)

toRef( 1)

// creates a readonly ref that calls the getter on .value access

toRef( => props.foo)

// returns existing refs as-is

toRef(existingRef)

使用getter调用 toRef 类似于 computed ,但当getter只是在没有昂贵计算的情况下执行属性访问时,效率会更高。新的 toValue 实用程序方法提供了相反的,将值/获取器/引用标准化为值:

toValue( 1) // --> 1

toValue(ref( 1)) // --> 1

toValue( => 1) // --> 1

toValue 可以在可组合物中代替 unref ,以便您的可组合物可以接受获取者作为响应性数据源:

// before: allocating unnecessary intermediate refs

useFeature(computed( => props.foo))

useFeature(toRef(props, 'foo'))

// after: more efficient and succinct

useFeature( => props.foo)

toRef 和 toValue 之间的关系与 ref 和 unref 之间的关系相似,主要区别是getter函数的特殊处理。

  • 详情: PR#7997[23]

JSX导入源支持

目前,Vue的类型会自动注册全局JSX类型。这可能会导致与其他需要JSX类型推理的库一起使用的冲突,特别是React。从3.3开始,Vue支持通过Type的 jsxImportSource[24] 选项指定JSX命名空间。这允许用户根据他们的用例选择全局或每个文件选择加入。为了向后兼容,3.3仍然在全球范围内注册JSX命名空间。 我们计划在3.4中删除默认的全局注册。如果您将TSX与Vue一起使用,您应该在升级到3.3后将显式 jsxImportSource 添加到 tsconfig.json ,以避免在3.4中损坏。

4维护基础设施改进

此版本基于许多维护基础设施改进,使我们能够更自信地更快地移动:

  • 通过将类型检查与 rollup 构建分开,并从 rollup-plugin-type2 移动到 rollup-plugin-esbuild ,构建速度快10倍。

  • 通过从Jest 迁移到 Vitest[25] 来加快测试速度。

  • 通过从 @microsoft/api-extractor 移动到 rollup-plugin-dts 更快地生成类型。

  • 通过 ecosystem-ci [26] 进行综合回归测试-在发布前捕获主要生态系统依赖项的回归!

按照计划,我们的目标是在2023年开始发布更小、更频繁的功能。敬请期待!

参考资料

[1]

Vue语言工具: https://github.com/vuejs/language-tools/

[2]

上的完整更改日志: https://github.com/vuejs/core/blob/main/CHANGELOG.md#330-2023-05-08

[3]

<脚本设置> + Type DX改进: https://blog.vuejs.org/posts/vue-3-3#-setup-type-dx-improvements

[4]

宏中的导入和复杂类型支持: https://blog.vuejs.org/posts/vue-3-3#imported-and-complex-types-support-in-macros

[5]

通用组件: https://blog.vuejs.org/posts/vue-3-3#generic-components

[6]

更符合人体工程学的定义Emits: https://blog.vuejs.org/posts/vue-3-3#more-ergonomic-defineemits

[7]

带有定义插槽的类型插槽: https://blog.vuejs.org/posts/vue-3-3#typed-slots-with-defineslots

[8]

实验特征: https://blog.vuejs.org/posts/vue-3-3#experimental-features

[9]

响应式 props 解构: https://blog.vuejs.org/posts/vue-3-3#reactive-props-destructure

[10]

定义模型: https://blog.vuejs.org/posts/vue-3-3#definemodel

[11]

其他值得注意的功能: https://blog.vuejs.org/posts/vue-3-3#other-notable-features

[12]

定义选项: https://blog.vuejs.org/posts/vue-3-3#defineoptions

[13]

使用toRef和toValue提供更好的Getter支持: https://blog.vuejs.org/posts/vue-3-3#better-getter-support-with-toref-and-tovalue

[14]

JSX导入源支持: https://blog.vuejs.org/posts/vue-3-3#jsx-import-source-support

[15]

维护基础设施改进: https://blog.vuejs.org/posts/vue-3-3#maintenance-infrastructure-improvements

[16]

PR#8083: https://github.com/vuejs/core/pull/8083

[17]

#436: https://github.com/vuejs/rfcs/discussions/436

[18]

通用 defineComponent -PR#7963: https://github.com/vuejs/core/pull/7963

[19]

标记的元组元素: https://www.typelang.org/docs/handbook/release-notes/type-4-0.html#labeled-tuple-elements

[20]

PR#7982: https://github.com/vuejs/core/issues/7982

[21]

RFC#502: https://github.com/vuejs/rfcs/discussions/502

[22]

#503: https://github.com/vuejs/rfcs/discussions/503

[23]

PR#7997: https://github.com/vuejs/core/pull/7997

[24]

jsxImportSource: https://www.typelang.org/tsconfig#jsxImportSource

[25]

Vitest: https://vitest.dev/

[26]

ecosystem-ci : https://github.com/vuejs/ecosystem-ci

• 面试官:聊一聊Java 泛型通配符 T,E,K,V,?

• 阿里一面:如何保证API接口数据安全?

• 0.2秒居然复制了100G文件?

• Java17,有史以来最快 JDK!

最近写了一套 6000 页的 Java 学习手册,以及珍藏四本 Java 人必读4大神器,分享到知乎已经 3 万赞了!

每篇文章图文并茂,附有源码。还有电子书合集

如果你想获得完整PDF可以通过以下方式获得

资料获取方法

  1. 即可领取
  2. 在后台回复关键词 002

明天见(。・ω・。)返回搜狐,查看更多

责任编辑:

平台声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()
大家都在看
推荐阅读