Vue 3.3 正式发布,代号:Rurouni Kenshin

简介: Vue 3.3 正式发布,代号:Rurouni Kenshin

5 月 11 日,Vue 3.3 正式发布,代号 Rurouni Kenshin。本次更新主要针对开发者体验进行了改进,特别是在使用 TypeScript 时的 SFC <script setup>。与 Vue 语言工具(以前称为 Volar)1.6 的发布相结合,解决了在使用 TypeScript 时存在的许多长期困扰问题。下面就来看看 Vue 3.3 版本中的重点功能!

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

SFC中的 <script setup> 和 TypeScript DX 改进

宏中的导入和复杂类型支持

在之前的版本中,用于 definePropsdefineEmits 的类型参数位置使用的类型被限制为本地类型,并且仅支持类型字面量和接口。这是因为 Vue 需要能够分析 props 接口上的属性以生成相应的运行时选项。

此限制现已在 3.3 中解决。 编译器现在可以解析导入的类型,并支持一组有限的复杂类型:

javascript

复制代码

<script setup lang="ts">import type { Props } from'./foo'// imported + intersection typedefineProps<Props & { extraProp?: string }>()</script>

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

通用组件

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

javascript

复制代码

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

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

javascript

复制代码

<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

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

javascript

复制代码

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

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

javascript

复制代码

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

在类型字面量中,键是事件名称,值是指定附加参数的数组类型。虽然不是必需的,但可以使用带标签的元组元素来明确表示,就像上面的示例中一样。

调用签名语法仍然受支持。

使用 defineSlots 的类型插槽

新的 defineSlots 宏可用于声明预期的插槽及其相应的预期插槽 props:

javascript

复制代码

<script setup lang="ts">defineSlots<{  default?: (props: { msg: string }) => any  item?: (props: { id: number }) => any}>()</script>

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

当前的一些限制:

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

defineComponent 用法也有对应的 slots 选项。 这两个 API 都没有运行时影响,并且纯粹用作 IDE 和 vue-tsc 的类型提示。

实验功能

响应式 Props 解构

以前是现在已删除的 Reactivity Transform 的一部分,响应式 props 解构已拆分为单独的功能。

该功能允许解构的 props 保持响应性,并提供更符合人体工程学的声明 props 默认值的方式:

javascript

复制代码

<script setup>
import { watchEffect } from 'vue'
const { msg = 'hello' } = defineProps(['msg'])
watchEffect(() => {
   // 在 watchers 和 computed getters 中访问 `msg`
   // 将其作为依赖项进行跟踪,就像访问 `props.msg` 一样
  console.log(`msg is: ${msg}`)
})
</script>
<template>{{ msg }}</template>

defineModel

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

<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

javascript

复制代码

<script setup>
const modelValue = defineModel()
console.log(modelValue.value)
</script>
<template>
  <input v-model="modelValue" />
</template>

其他特性

defineOptions

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

javascript

复制代码

<script setup>defineOptions({ inheritAttrs: false })
</script>

使用 toRef 和 toValue 实现更好的 getter 支持

toRef 已得到增强以支持将值/getters/现有 refs 规范化为 refs

javascript

复制代码

// 相当于 ref(1)toRef(1)
// 创建一个 readonly ref,在 .value 访问时调用 gettertoRef(() => props.foo)
// 按原样返回现有 refstoRef(existingRef)

使用 getter 调用 toRef 类似于 computed,但是当 getter 只执行属性访问而没有昂贵的计算时,可以更高效。

新的 toValue 工具方法提供相反的功能,即将值/ getter / ref 规范化为值:

javascript

复制代码

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

toValue 可以在组合式函数中代替 unref,以便组合式函数可以接受 getter 作为响应式数据源:

javascript

复制代码

// 以前:分配不必要的中间引用useFeature(computed(() => props.foo))
useFeature(toRef(props, 'foo'))

// 现在:更高效和简洁useFeature(() => props.foo)

toReftoValue 之间的关系类似于 refunref 之间的关系,主要区别在于 getter 函数的特殊处理。

JSX 导入源支持

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

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

为了向后兼容,3.3 仍然全局注册 JSX 命名空间。计划在 3.4 中删除默认的全局注册。如果正在使用 TSX 和 Vue,请在升级到 3.3 后在 tsconfig.json 中添加显式的 jsxImportSource,以避免在 3.4 中出现问题。

维护基础设施改进

此版本建立在许多维护基础设施改进的基础上,这使得 Vue 团队能够更有信心地更快地行动:

  • 通过将类型检查与汇总构建分开并从 rollup-plugin-typescript2 移动到 rollup-plugin-esbuild,构建速度提高 10 倍。
  • 通过从 Jest 转移到 Vitest 来加快测试速度。
  • 通过从 @microsoft/api-extractor 转移到 rollup-plugin-dts 来更快地生成类型。
  • 通过 ecosystem-ci 进行综合回归测试,在发布前捕获主要生态系统依赖项中的回归。

按照计划,Vue 团队的目标是在 2023 年开始发布更小、更频繁的功能版本,敬请期待!

参考:blog.vuejs.org/posts/vue-3…

相关文章
|
22天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
126 64
|
22天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
101 60
|
22天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
28 8
|
21天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
21 1
|
21天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
32 1
|
22天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
1月前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
1月前
|
JavaScript 索引
Vue 3.x 版本中双向数据绑定的底层实现有哪些变化
从Vue 2.x的`Object.defineProperty`到Vue 3.x的`Proxy`,实现了更高效的数据劫持与响应式处理。`Proxy`不仅能够代理整个对象,动态响应属性的增删,还优化了嵌套对象的处理和依赖追踪,减少了不必要的视图更新,提升了性能。同时,Vue 3.x对数组的响应式处理也更加灵活,简化了开发流程。
|
1月前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
75 7
|
1月前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
98 3