您现在的位置是:首页 >其他 >Vue3.3 正式发布网站首页其他

Vue3.3 正式发布

海海呐 2024-06-17 10:19:28
简介Vue3.3 正式发布

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

此版本专注于改进开发人员体验 - 特别是 SFC<script setup>与 TypeScript 的使用。与Vue 语言工具(以前称为 Volar)的 1.6 版本一起,我们解决了将 Vue 与 TypeScript 一起使用时许多长期存在的痛点。

这篇文章概述了 3.3 中突出显示的功能。有关更改的完整列表,请查阅GitHub 上的完整更改日志

依赖更新

升级到 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)

<script setup> + TypeScript 开发体验改善

支持类型导入和复杂类型

以前,在 definePropsdefineEmits 的类型仅支持本地类型不能使用 import,并且仅支持类型字面量和 interface。这是因为 Vue 需要能够分析 props 接口上的属性,以生成相应的运行时选项。

这个限制现在在 3.3 中得到解决。编译器现在可以解析导入的类型,并支持有限的复杂类型

<script setup lang="ts">
import type { Props } from './foo'

// imported + intersection type
defineProps<Props & { extraProp?: string }>()
</script>

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

泛型组件

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

<script setup lang="ts" generic="T">
defineProps<{
  items: T[]
  selected: T
}>()
</script>

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

<script setup lang="ts" generic="T extends string | number, U extends Item">
import type { Item } from './types'
defineProps<{
  id: T
  list: U[]
}>()
</script> 

此功能在最新版本的 volar / vue-tsc 中默认启用。 

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

// BEFORE
const emit = defineEmits<{
  (e: 'foo', id: number): void
  (e: 'bar', name: string, ...rest: any[]): void
}>()

该类型与 emit 的返回类型匹配,但编写起来有点冗长和笨拙。3.3 引入了一种更符合人体工程学的声明带有类型的 emits 的方式:

// AFTER

const emit = defineEmits<{

foo: [id: number]

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

}>()

在类型文字中,键是事件名称,值是指定附加参数的数组类型。虽然不是必需的,但您可以使用带标签的元组元素来明确显示,如上例所示。

以前的函数调用签名语法仍然受支持。

使用 defineSlots 设置 slots 类型

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

<script setup lang="ts">

defineSlots<{

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

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

}>()

</script>

defineSlots()只接受类型参数,不接受运行时参数。类型参数应该是类型字面量,其中属性键是插槽名称,值是插槽函数。该函数的第一个参数是插槽期望接收的道具,其类型将用于模板中的插槽道具。的返回值defineSlots与从 返回的插槽对象相同useSlots

当前的一些限制:

  • volar / vue-tsc 中尚未实现必需的插槽检查。
  • 插槽函数返回类型目前被忽略,可以是any,但我们将来可能会利用它来检查插槽内容。

还有相应的使用slots选项defineComponent。这两个 API 都没有运行时影响,并且纯粹用作 IDE 和vue-tsc.

实验功能

反应性道具解构

以前是现已删除的 Reactivity Transform 的一部分,reactive props destructure 已拆分为一个单独的功能。

该功能允许解构的道具保留反应性,并提供更符合人体工程学的方式来声明道具默认值:

<script 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}`)

})

</script>

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

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

defineModel

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

<!-- BEFORE -->

<script setup>

const props = defineProps(['modelValue'])

const emit = defineEmits(['update:modelValue'])

console.log(props.modelValue)

function onInput(e) {

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

}

</script>

<template>

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

</template>

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

<!-- AFTER -->

<script setup>

const modelValue = defineModel()

console.log(modelValue.value)

</script>

<template>

<input v-model="modelValue" />

</template>

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

其他显着特点

defineOptions

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

<script setup>

defineOptions({ inheritAttrs: false })

</script>

更好的Getter支持toRef和toValue

toRef已得到增强以支持将值/获取器/现有引用规范化为引用:

// 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实用方法提供了相反的方法,将 values / getters / refs 规范化为值:

toValue(1) // --> 1

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

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

 toValue可以在可组合项中使用代替,unref以便您的可组合项可以接受 getter 作为反应式数据源:

// before: allocating unnecessary intermediate refs

useFeature(computed(() => props.foo))

useFeature(toRef(props, 'foo'))

// after: more efficient and succinct

useFeature(() => props.foo)

toRefand之间的关系toValue类似于refand之间的关系unref,主要区别在于getter 函数的特殊处理。

JSX 导入源支持

目前,Vue 的类型会自动注册全局 JSX 类型。这可能会导致与需要 JSX 类型推断的其他库一起使用时发生冲突,尤其是 React。

从 3.3 开始,Vue 支持通过 TypeScript 的jsxImportSource选项指定 JSX 命名空间。这允许用户根据他们的用例选择全局或每个文件选择加入。

为了向后兼容,3.3 仍然全局注册 JSX 命名空间。我们计划在 3.4 中移除默认的全局注册。jsxImportSource如果您将 TSX 与 Vue 一起使用,则应在升级到 3.3 后向您添加 explicittsconfig.json以避免在 3.4 中损坏。

最后

如果这篇文章对您有所帮助,可以点赞加收藏哈

原文地址:Announcing Vue 3.3 | The Vue Point

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。