百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

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

csdh11 2024-11-30 14:14 4 浏览

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

此版本专注于开发人员体验改进-特别是SFC<script setup>与TypeScript的使用。与Vue语言工具[1](以前称为Volar)的1.6版本一起,我们在将Vue与TypeScript一起使用时解决了许多长期存在的痛点。这篇文章概述了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)
  • \<脚本设置> + TypeScript DX改进[3]
    • 宏中的导入和复杂类型支持[4]
    • 通用组件[5]
    • 更符合人体工程学的定义Emits[6]
    • 带有定义插槽的类型插槽[7]
  • 实验特征[8]
    • 响应式 props 解构[9]
    • 定义模型[10]
  • 其他值得注意的功能[11]
    • 定义选项[12]
    • 使用toRef和toValue提供更好的Getter支持[13]
    • JSX导入源支持[14]
  • 维护基础设施改进[15]

1<script setup>+ TypeScript DX改进

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

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

vue

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

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

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

  • 详情:PR#8083[16]

通用组件

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

vue

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

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

vue

<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中默认启用。

  • 讨论:RFC#436[17]
  • 相关:通用`defineComponent()`\-PR#7963[18]

更符合人体工程学defineEmits

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

ts

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

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

ts

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

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

键入的插槽defineSlots

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

vue

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

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

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

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

  • 详情:PR#7982[20]

2实验特征

响应式 prop 解构

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

vue

<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>

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

  • 详情:RFC#502[21]

defineModel

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

vue

<!-- 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宏的使用。宏会自动注册一个Props,并返回一个可以直接突变的引用:

vue

<!-- AFTER -->
<script setup>
const modelValue = defineModel()
console.log(modelValue.value)
</script>

<template>
  <input v-model="modelValue" />
</template>

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

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

3其他值得注意的功能

defineOptions

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

vue

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

使用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)

toReftoValue之间的关系与refunref之间的关系相似,主要区别是getter函数的特殊处理。

  • 详情:PR#7997[23]

JSX导入源支持

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

4维护基础设施改进

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

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

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

相关推荐

Micheal Nielsen&#39;s神经网络学习之二

依然是跟着MichaelNielsen的神经网络学习,基于前一篇的学习,已经大概明白了神经网络的基本结构和BP算法,也能通过神经网络训练数字识别功能,之后我试验了一下使用神经网络训练之前的文本分类,...

CocoaPods + XCTest进行单元测试 c单元测试工具

在使用XCTest进行单元测试时,我们经常会遇到一些CocoaPods中的开源框架的调用,比如“Realm”或“Alamofire”在测试的时候,如果配置不当,会导致“frameworknotfo...

Java基础知识回顾第四篇 java基础讲解

1、&和&&的区别作为逻辑运算符:&(不管左边是什么,右边都参与运算),&&(如果左边为false,右边则不参与运算,短路)另外&可作为位运算符...

项目中的流程及类似业务的设计模式总结

说到业务流程,可能是我做过的项目中涉及业务最多的一个方面了。除了在流程设计之外,在一些考核系统、产业审批、还有很多地方,都用到相似的设计思路,在此一并总结一下。再说到模式,并不是因为流行才用这个词,而...

联想三款显示器首批获得 Eyesafe Certified 2.0 认证

IT之家7月31日消息,据外媒报道,三款全新联想显示器是全球首批满足EyesafeCertified2.0的设备。据报道,联想获得EyesafeCertified2.0认证的显...

maven的生命周期,插件介绍(二) 一个典型的maven构建生命周期

1.maven生命周期一个完整的项目构建过程通常包括清理、编译、测试、打包、集成测试、验证、部署等步骤,Maven从中抽取了一套完善的、易扩展的生命周期。Maven的生命周期是抽象的,其中的具体任务都...

多线程(3)-基于Object的线程等待与唤醒

概述在使用synchronized进行线程同步中介绍了依赖对象锁定线程,本篇文章介绍如何依赖对象协调线程。同synchronized悲观锁一样,线程本身不能等待与唤醒,也是需要对象才能完成等待与唤醒的...

jquery mobile + 百度地图 + phonegap 写的一个&quot;校园助手&quot;的app

1jquerymobile+百度地图+phonegap写的一个"校园助手"的app,使用的是基于Flat-UI的jQueryMobile,请参考:https://github.com/...

Apache 服务启动不了 apache系统服务启动不了

{我是新手,从未遇到此问题,请各位大大勿喷}事由:今天早上上班突然发现公司网站出现问题。经过排查,发现是Apache出现问题。首先检查配置文件没有出问题后,启动服务发现Apache服务能启动,但是没法...

健康债和技术债都不能欠 公众号: 我是攻城师(woshigcs)

在Solr4.4之后,Solr提供了SolrCloud分布式集群的模式,它带来的主要好处是:(1)大数据量下更高的性能(2)更好扩展性(3)更高的可靠性(4)更简单易用什么时候应该使用Sol...

Eye Experience怎么用?HTC告诉你 eyebeam怎么用

IT之家(www.ithome.com):EyeExperience怎么用?HTC告诉你HTC上周除了发布HTCDesireEYE自拍机和HTCRE管状运动相机之外,还发布了一系列新的智能手机...

Android系统应用隐藏和应用禁止卸载

1、应用隐藏与禁用Android设置中的应用管理器提供了一个功能,就是【应用停用】功能,这是针对某些系统应用的。当应用停用之后,应用的图标会被隐藏,但apk还是存在,不会删除,核心接口就是Packag...

计算机软件技术分享--赠人玫瑰,手遗余香

一、Netty介绍Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。也就是说,Netty...

Gecco爬虫框架的线程和队列模型 爬虫通用框架

简述爬虫在抓取一个页面后一般有两个任务,一个是解析页面内容,一个是将需要继续抓取的url放入队列继续抓取。因此,当爬取的网页很多的情况下,待抓取url的管理也是爬虫框架需要解决的问题。本文主要说的是g...

一点感悟(一) 初识 初读感知的意思

时间过得很快,在IT业已从业了两年多。人这一辈子到底需要什么,在路边看着人来人往,大部分人脸上都是很匆忙。上海真是一个魔都,它有魅力,有底蕴,但是一个外地人在这里扎根置业,真的是举全家之力,还贷3...