从争议到巅峰:Vue3 的奇迹之旅 —— 从‘海贼王’到‘灌篮高手’的变革历程

Hello,大家好,我是 Sunday。

Vue 官方团队在 2023 年的最后两天发布了 Vue 3.4 的版本命名为 "Slam Dunk"(灌篮高手)。Vue3 自 2020 年发布,到目前为止已经有 三年半 的时间(想不到吧,Vue3 已经发布了这么久了)。期间经历了很多关键节点的变化,从最初的 被人诟病 到现在的 "全面认可" 中间到底经历了什么?

那么在 23 年末的今天,就让咱们回顾一下整个 Vue3 的生命历程,看看从 海贼王灌篮高手 的变化吧~~

2020年9月18日:Vue 3.0 海贼王 -- 发布

Vue 3 于 2020年9月18日 正式发布,命名 海贼王 。 Vue 官方团队雄心壮志,宣布了很多全新的特性,比如:Composition API但是: 简陋的 setup 函数特性让很多开发者对 Composition API 的易用性产生了 "怀疑"。所以 海贼王 在一开始的推广中 并不顺利~

今天我们很自豪地宣布 Vue.js 3.0"海贼王"正式发布。该框架的这个新的主要版本提供了改进的性能、更小的包大小、更好的 TypeScript 集成、用于处理大规模用例的新 API,并为该框架的长期未来迭代奠定了坚实的基础。

3.0 版本代表了超过 2 年的开发工作,包括 30 多个 RFC、2,600 多个提交、来自 99 个贡献者的 628 个拉取请求,以及核心存储库之外的大量开发和文档工作。我们要对接受这一挑战的团队成员、拉取请求的贡献者、提供财务支持的赞助商和支持者以及参与我们的设计讨论并为预发布提供反馈的更广泛的社区表示最深切的感谢。 -发布版本。 Vue 是一个为社区创建并由社区维持的独立项目,如果没有您的持续支持,Vue 3.0 就不可能实现。

进一步深化"渐进框架"概念

Vue 从一开始就有一个简单的使命:成为一个任何人都可以快速学习的平易近人的框架。随着我们的用户群的增长,该框架的范围也随之扩大,以适应不断增长的需求。随着时间的推移,它演变成我们所说的"渐进式框架":一个可以逐步学习和采用的框架,同时在用户处理越来越多的要求较高的场景时提供持续的支持。

如今,Vue 在全球拥有超过 130 万用户*,我们看到 Vue 被用于各种各样的场景,从传统服务器渲染页面上的少量交互,到具有数百个组件的成熟单页面应用程序。 Vue 3 进一步增强了这种灵活性。

分层内部模块​

Vue 3.0 核心仍然可以通过简单的 <script> 标签使用,但其内部结构已从头开始重写为解耦模块的集合。新的架构提供了更好的可维护性,并允许最终用户通过树摇动将运行时大小减少一半。

这些模块还公开了较低级别的 API,可解锁许多高级用例:

编译器支持自定义 AST 转换以进行构建时自定义(例如构建时 i18n) 核心运行时提供一流的 API,用于创建针对不同渲染目标(例如本机移动、WebGL 或终端)的自定义渲染器。默认 DOM 渲染器是使用相同的 API 构建的。 @vue/reactivity 模块导出提供对 Vue 反应性系统的直接访问的函数,并且可以用作独立包。它可以与其他模板解决方案(例如 lit-html)配合使用,甚至可以在非 UI 场景中使用。

用于应对规模问题的新 API​

2.x 基于对象的 API 在 Vue 3 中基本保持不变。然而,3.0 还引入了 Composition API------一组新的 API,旨在解决大规模应用程序中 Vue 使用的痛点。 Composition API 构建在反应性 API 之上,支持类似于 React hooks 的逻辑组合和重用、更灵活的代码组织模式以及比 2.x 基于对象的 API 更可靠的类型推断。

Composition API 还可以通过 @vue/composition-api 插件与 Vue 2.x 一起使用,并且已经有适用于 Vue 2 和 3 的 Composition API 实用程序库(例如 vueuse、vue-composable)。

性能改进​

与 Vue 2 相比,Vue 3 在包大小(通过 Tree-Shaking 减少最多 41%)、初始渲染(快 55%)、更新(快 133%)和内存使用方面表现出了显着的性能改进(最多减少 54%)。

在 Vue 3 中,我们采用了"编译器通知的虚拟 DOM"方法:模板编译器执行积极的优化并生成渲染函数代码,以提升静态内容,为绑定类型留下运行时提示,最重要的是,展平内部的动态节点减少运行时遍历成本的模板。因此,用户可以两全其美:从模板获得编译器优化的性能,或者在用例需要时通过手动渲染函数进行直接控制。

改进了 TypeScript 集成​

Vue 3 的代码库是用 TypeScript 编写的,具有自动生成、测试和捆绑的类型定义,因此它们始终是最新的。组合 API 非常适合类型推断。 Vetur 是我们的官方 VSCode 扩展,现在利用 Vue 3 改进的内部类型支持模板表达式和 props 类型检查。哦,如果您愿意的话,Vue 3 的输入完全支持 TSX。

实验特点​

我们为单文件组件(SFC,又名 .vue 文件)提出了两个新功能:

  • <script setup>:在 SFC 内使用 Composition API 的语法糖
  • <style vars>:SFC 内状态驱动的 CSS 变量

这些功能已在 Vue 3.0 中实现并可用,但仅出于收集反馈的目的而提供。在 RFC 合并之前,它们将保持实验状态。

我们还实现了一个当前未记录的 <Suspense> 组件,它允许在初始渲染或分支切换时等待嵌套的异步依赖项(异步组件或具有异步 setup() 的组件)。我们正在与 Nuxt.js 团队一起测试和迭代此功能(Nuxt 3 即将推出),并且可能会在 3.1 中对其进行巩固。

分阶段发布流程

Vue 3.0 的发布标志着该框架已基本准备就绪。虽然某些框架子项目可能仍需要进一步工作才能达到稳定状态(特别是开发工具中的路由器和 Vuex 集成),但我们相信现在适合使用 Vue 3 启动新的绿色项目。我们还鼓励库作者开始升级您的项目以支持 Vue 3。

迁移和 IE11 支持​

由于时间限制,我们推迟了迁移构建(具有 v2 兼容行为的 v3 构建 + 迁移警告)和 IE11 构建,并计划在 2020 年第四季度重点关注它们。因此,计划迁移现有 v2 应用程序或需要IE11 支持此时应该意识到这些限制。

下一步​

发布后的短期内,我们将重点关注:

  • 迁移构建
  • IE11支持
  • 新开发工具中的路由器和 Vuex 集成
  • Vetur 中模板类型推断的进一步改进

目前,Vue 3 和 v3 目标项目的文档网站、GitHub 分支和 npm dist 标签将保持在 next-driven 状态。这意味着 npm install vue 仍将安装 Vue 2.x,而 npm install vue@next 将安装 Vue 3。我们计划在 2021 年初将所有文档链接、分支和 dist 标签切换为默认 3.0。

与此同时,我们已经开始规划 2.7,这将是 2.x 版本系列的最后一个计划的次要版本 。 2.7 将从 v3 向后移植兼容改进,并对使用 v3 中删除/更改的 API 发出警告,以帮助潜在的迁移。我们计划在 2021 年第一季度开发 2.7,发布后将直接成为 LTS,维护周期为 18 个月。

2021年8月5日:Vue 3.2 Quintessential Quintuplets(5大变化) -- 发布

Vue 3.2 提供了 五种全新的改进 。 3.2 版本也成了 Vue3 之后稳定期最长的版本。在这个版本中 <script setup>的全新语法糖占据了主流,同时也使得 Vue3 正式成为 最受欢迎 的 Vue 版本

全新SFC的功能

单文件组件(SFC,又名 .vue 文件)的两个新功能已脱离实验状态,现在被认为是稳定的:

  • <script setup> 是一个编译时语法糖,可以极大地改善在 SFC 内使用 Composition API 时的人体工程学。

  • <style> v-bind 在 SFC <style> 标记中启用组件状态驱动的动态 CSS 值。

以下是结合使用这两个新功能的示例组件:

xml 复制代码
<script setup>
import { ref } from 'vue'

const color = ref('red')
</script>

<template>
  <button @click="color = color === 'red' ? 'green' : 'red'">
    Color is: {{ color }}
  </button>
</template>

<style scoped>
button {
  color: v-bind(color);
}
</style>

在 SFC Playground 中尝试一下,或者阅读它们各自的文档:

  • <script setup>
  • <style> v-bind

<script setup> 的基础上,我们还有一个新的 RFC,用于通过启用编译器的糖来改善引用使用的人体工程学 - 请在此处分享您的反馈。

Web Components

Vue 3.2 引入了一个新的 DefineCustomElement 方法,可以使用 Vue 组件 API 轻松创建原生自定义元素:

js 复制代码
import { defineCustomElement } from 'vue'

const MyVueElement = defineCustomElement({
  // normal Vue component options here
})

// Register the custom element.
// After registration, all `<my-vue-element>` tags
// on the page will be upgraded.
customElements.define('my-vue-element', MyVueElement)

该 API 允许开发人员创建由 Vue 支持的 UI 组件库,这些组件库可以与任何框架一起使用,或者根本不需要框架。我们还在文档中添加了关于在 Vue 中使用和创建 Web 组件的新部分。

性能改进

3.2 包括对 Vue 反应系统的一些重大性能改进,这要归功于 @basvanmeurs 的出色工作。具体来说:

  • 更高效的引用实现(读取速度加快约 260%/写入速度加快约 50%)
  • 依赖性跟踪速度加快约 40%
  • 内存使用量减少约 17%

模板编译器还获得了许多改进:

  • 普通元素 VNode 的创建速度提高约 200%
  • 更积极的持续提升

最后,有一个新的 v-memo 指令,它提供了记忆部分模板树的功能。 v-memo 命中不仅允许 Vue 跳过虚拟 DOM 比较,还可以完全跳过新 VNode 的创建。尽管很少需要,但它提供了一个逃生舱口,可以在某些情况下(例如大型 v-for 列表)发挥最大性能。

v-memo(一行添加)的使用使 Vue 跻身 js-framework-benchmark 中最快的主流框架之列:

服务端渲染

3.2 中的 @vue/server-renderer 包现在提供了一个 ES 模块构建,它也与 Node.js 内置程序解耦。这使得可以捆绑和利用 @vue/server-renderer 在非 Node.js 运行时(例如 CloudFlare Workers 或 Service Workers)中使用。

我们还改进了流渲染 API,提供了渲染到 Web Streams API 的新方法。查看 @vue/server-renderer 的文档以获取更多详细信息。

Effect Scope API

3.2 引入了一个新的 Effect Scope API,用于直接控制反应效果(计算和观察者)的处理时间。它使得在组件上下文之外利用 Vue 的反应性 API 变得更加容易,并且还解锁了组件内部的一些高级用例。

这是底层的 API,主要供库作者使用,因此建议阅读该功能的 RFC 以了解该功能的动机和用例。

2022年1月20日:Vue3 变为默认版本

得益于 Vue 3.2 的成功,Vue 官方团队宣布 自2022 年 2 月 7 日星期一起, Vue 3 将取代 Vue2 成为新的默认版本!

2022年7月1日:Vue 2的"绝唱" 火影忍者发布

Vue2 发布最后一个全新版本,代号 火影忍者 。该版本支持 Vue3 中的一些重要功能,比如 Composition API<script setup>。 不过这也标记着整个 Vue2 将逐步转化到 "维护期"。见证整个 Vue 崛起 Vue2 生命周期进入倒计时!

尽管 Vue 3 现在是默认版本,但我们了解到,由于依赖兼容性、浏览器支持要求或根本没有足够的带宽来升级,仍然有许多用户必须留在 Vue 2 上。在 Vue 2.7 中,我们向后移植了 Vue 3 中的一些最重要的功能,以便 Vue 2 用户也可以从中受益。

向后移植的功能

  • Composition API
  • SFC <script setup>
  • SFC CSS v-bind

此外,还支持以下API:

  • DefineComponent() 具有改进的类型推断(与 Vue.extend 相比)

  • h()、useSlot()、useAttrs()、useCssModules()

  • set()、del() 和 nextTick() 也在 ESM 构建中作为命名导出提供。

  • 还支持 emits 选项,但仅用于类型检查目的(不影响运行时行为)

2.7还支持在模板表达式中使用ESNext语法。当使用构建系统时,编译后的模板渲染函数将通过为普通 JavaScript 配置的相同加载器/插件。这意味着如果您为 .js 文件配置了 Babel,它也将应用于 SFC 模板中的表达式。

API暴露注意事项​

  • 在 ESM 构建中,这些 API 作为命名导出提供(并且仅限命名导出):
csharp 复制代码
import Vue, { ref } from 'vue'

Vue.ref // undefined, use named export instead
  • 在 UMD 和 CJS 构建中,这些 API 作为全局 Vue 对象的属性公开。
  • 当与外部化的 CJS 构建捆绑时,捆绑器应该能够在外部化 CJS 构建时处理 ESM 互操作。

与 Vue 3 的行为差异​

Composition API 使用 Vue 2 的基于 getter/setter 的反应系统进行反向移植,以确保浏览器兼容性。这意味着与 Vue 3 基于代理的系统存在一些重要的行为差异:

  • 所有 Vue 2 变更检测警告仍然适用。
  • reactive()、ref()和shallowReactive()将直接转换原始对象而不是创建代理。这意味着:
scss 复制代码
// true in 2.7, false in 3.x
reactive(foo) === foo
  • readonly() 确实创建了一个单独的对象,但它不会跟踪新添加的属性,并且不适用于数组。
  • 避免在reactive()中使用数组作为根值,因为如果没有属性访问,数组的突变将不会被跟踪(这将导致警告)。
  • 反应性 API 会忽略带有符号键的属性。

此外,以下功能明确未移植:

  • createApp() (Vue 2 没有独立的应用程序范围)
  • <script setup> 中的顶级await(Vue 2不支持异步组件初始化)
  • ❌ 模板表达式中的 TypeScript 语法(与 Vue 2 解析器不兼容)
  • ❌ 反应性变换(仍处于试验阶段)
  • ❌ 选项组件不支持暴露选项(但 <script setup> 支持 DefineExpose())。

2023年5月11日:Vue 3.3 浪客剑心 -- 发布

在 Vue 3.2 发布 21 个月之后,Vue 3.3 正式发布。这个版本以改进开发人员体验为主,特别是 <script setup> 与 TypeScript 的使用。同时 Volar 的支持将会更好

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

kotlin 复制代码
依赖项更新

升级到3.3时,建议同时更新以下依赖项:

掌侧/vue-tsc@^1.6.4
投票@^4.3.5
@vitejs/plugin-vue@^4.2.0
vue-loader@^17.1.0(如果使用 webpack 或 vue-cli)

<script setup> + TypeScript DX 改进

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

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

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

xml 复制代码
<script setup lang="ts">
import type { Props } from './foo'

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

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

通用组件​

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

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

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

xml 复制代码
<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 的类型参数仅支持调用签名语法:

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

该类型与emit的返回类型相匹配,但有点冗长并且写起来很困难。 3.3 引入了一种更符合直觉的用类型声明emits的方式:

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

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

仍然支持调用签名语法。

带有defineSlots的类型插槽​

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

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

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

当前的一些限制:

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

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

实验特性

反应式道具解构​

反应性道具解构以前是反应性变换的一部分,现在已被放弃,现已被分成一个单独的功能。

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

xml 复制代码
<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) 在打算更新 prop 时发出相应的 update:propName 事件
xml 复制代码
<!-- 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:

xml 复制代码
<!-- AFTER -->
<script setup>
const modelValue = defineModel()
console.log(modelValue.value)
</script>

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

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

其他需要注意的地方

defineOptions

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

xml 复制代码
<script setup>
defineOptions({ inheritAttrs: false })
</script>

toRef 和 toValue 提供更好的 Getter 支持

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

scss 复制代码
// 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 类似于计算,但当 getter 仅执行属性访问而不进行昂贵的计算时,效率会更高。

新的 toValue 实用方法提供了相反的功能,将值/获取器/引用规范化为值:

scss 复制代码
toValue(1) //       --> 1
toValue(ref(1)) //  --> 1
toValue(() => 1) // --> 1

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

scss 复制代码
// 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 函数的特殊处理。

JSX 导入源支持​

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

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

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

维护基础设施的改进

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

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

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

2023年12月28日:Vue 3.4 🏀 ♪灌篮高手♪ -- 发布

Vue 3.4 的版本对性能进行了很大的提升,比如:模板解析器速度提高了 2 倍,重构了响应系统、defineModel 绑定 props 性能进行了提升

潜在问题的处理

  • 为了充分利用 3.4 中的新功能,建议在升级到 3.4 时还更新以下依赖项:
    • Volar / vue-tsc@^1.8.27(必填)
    • @vitejs/plugin-vue@^5.0.0(如果使用 Vite)
    • nuxt@^3.9.0(如果使用 Nuxt)
    • vue-loader@^17.4.0(如果使用 webpack 或 vue-cli)
  • 如果将 TSX 与 Vue 结合使用,请检查已删除:全局 JSX 命名空间中所需的操作。
  • 确保您不再使用任何已弃用的功能(如果是,控制台中应该会出现警告)。它们可能已在 3.4 中被删除。

特色亮点

2倍更快的解析器和改进的SFC构建性能

在3.4中,我们完全重写了模板解析器。以前,Vue 使用递归下降解析器,该解析器依赖于许多正则表达式和前瞻搜索。新的解析器使用基于 htmlparser2 中的 tokenizer 的状态机 tokenizer,它仅迭代整个模板字符串一次。结果是解析器对于所有大小的模板来说始终是两倍的速度。得益于我们广泛的测试用例和生态系统-ci,它也 100% 向后兼容 Vue 最终用户。

在将新的解析器与系统的其他部分集成时,我们还发现了一些进一步提高整体 SFC 编译性能的机会。基准测试显示,在生成源映射的同时编译 Vue SFC 的脚本和模板部分时,性能提高了约 44%,因此 3.4 应该会加快大多数使用 Vue SFC 的项目的构建速度。但是,请注意,Vue SFC 编译只是现实项目中整个构建过程的一部分。与单独的基准测试相比,端到端构建时间的最终收益可能要小得多。

在 Vue 核心之外,新的解析器还将有利于 Volar / vue-tsc 以及需要解析 Vue SFC 或模板的社区插件的性能,例如Vue 宏。

更高效的反应系统

3.4 还对反应性系统进行了重大重构,目标是提高计算属性的重新计算效率。

为了说明正在改进的内容,让我们考虑以下场景:

scss 复制代码
const count = ref(0)
const isEven = computed(() => count.value % 2 === 0)

watchEffect(() => console.log(isEven.value)) // logs true

count.value = 2 // logs true again

在 3.4 之前,每次 count.value 更改时,watchEffect 的回调都会触发,即使计算结果保持不变。通过 3.4 后的优化,现在仅当计算结果实际发生更改时才会触发回调。

另外,在3.4中:

  • 多个计算的 dep 更改仅触发同步效果一次。
  • 数组的 shift, unshift, splice 仅触发一次同步效果。

除了基准测试中显示的收益之外,这还可以减少许多场景中不必要的组件重新渲染,同时保留完全的向后兼容性。

defineModel 更加稳定

DefineModel 是一个新的 <script setup> 宏,旨在简化支持 v-model 的组件的实现。它之前作为实验性功能在 3.3 中发布,并在 3.4 中升级为稳定状态。现在,它还为 v-model 修饰符的使用提供了更好的支持。

相关文档:

v-bind 支持同名速记

现在,您可以缩短以下内容:

ruby 复制代码
<img :id="id" :src="src" :alt="alt">

修改为:

ruby 复制代码
<img :id :src :alt>

过去经常需要此功能。最初,我们担心它的用法会与布尔属性混淆。然而,在重新审视该功能之后,考虑到 v-bind 的动态特性,我们现在认为 v-bind 的行为更像 JavaScript 而不是本机属性是有意义的。

改善水合作用不匹配错误

3.4 对水合不匹配错误消息进行了多项改进:

  • 提高了措辞的清晰度(由服务器呈现与客户端预期呈现)。
  • 该消息现在包含有问题的 DOM 节点,因此您可以在页面或元素面板中快速找到它。
  • 水合作用不匹配检查现在也适用于类、样式和其他动态绑定属性。

此外,3.4 还添加了一个新的编译时标志 __VUE_PROD_HYDRATION_MISMATCH_DETAILS__,可用于强制水合不匹配错误包含完整的详细信息,即使在生产中也是如此。

错误代码和编译时标志引用

为了减少包的大小,Vue 在生产版本中删除了长错误消息字符串。然而,这意味着生产中的错误处理程序捕获的错误将收到简短的错误代码,如果不深入 Vue 的源代码,这些代码很难破译。

为了改进这一点,我们在文档中添加了生产错误参考页面。错误代码是从最新版本的 Vue 稳定版本自动生成的。

我们还添加了编译时标志参考,其中包含有关如何为不同构建工具配置这些标志的说明。

删除了不推荐使用的功能

全局JSX命名空间

从 3.4 开始,Vue 默认不再注册全局 JSX 命名空间。这对于避免与 React 的全局命名空间冲突是必要的,以便两个库的 TSX 可以在同一项目中共存。这不会影响使用最新版本 Volar 的仅 SFC 用户。

如果您使用 TSX,有两种选择:

  • 在升级到 3.4 之前,在 tsconfig.json 中将 jsxImportSource 显式设置为"vue"。您还可以通过在文件顶部添加 /* @jsxImportSource vue */ 注释来​​选择加入每个文件。

  • 如果您的代码依赖于全局 JSX 命名空间的存在,例如使用 JSX.Element 等类型,您可以通过显式引用 vue/jsx(注册全局 JSX 命名空间)来保留确切的 3.4 之前的全局行为。

请注意,这是次要版本中仅类型的重大更改,符合我们的发布政策。

其他已删除的功能

  • Reactivity Transform 在 3.3 中被标记为已弃用,现已在 3.4 中删除。由于该功能处于实验阶段,因此此更改不需要专业。希望继续使用该功能的用户可以通过 Vue Macros 插件来实现。
  • app.config.unwrapInjectedRef 已被删除。它已被弃用并在 3.3 中默认启用。在 3.4 中,无法再禁用此行为。
  • 模板中的 @vnodeXXX 事件侦听器现在是编译器错误,而不是弃用警告。请改用 @vue:XXX 侦听器。
  • v-is 指令已被删除。它在 3.3 中已被弃用。请使用带有 vue: 前缀的 is 属性。

前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax