发布时间

Vue 2.7 "Naruto" 发布

作者

naruto-vue-logo

今天我们很高兴地宣布 Vue 2.7 "Naruto" 已发布!


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

移植的功能

此外,以下 API 也受支持

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

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

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

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

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

关于 API 暴露的说明

  • 在 ESM 构建中,这些 API 作为命名导出提供(并且仅作为命名导出提供)

    js
    import Vue, { ref } from 'vue'
    
    Vue.ref // undefined, use named export instead
  • 在 UMD 和 CJS 构建中,这些 API 作为全局 Vue 对象上的属性暴露。

  • 当使用 CJS 构建外部化进行捆绑时,捆绑器应该能够在外部化 CJS 构建时处理 ESM 互操作性。

与 Vue 3 的行为差异

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

  • 所有 Vue 2 更改检测注意事项 仍然适用。

  • reactive()ref()shallowReactive() 将直接转换原始对象,而不是创建代理。这意味着

    js
    // 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 解析器不兼容)
  • ❌ 响应式转换(仍在实验阶段)
  • expose 选项不支持选项组件(但 defineExpose()<script setup> 中受支持)。

升级指南

Vue CLI / webpack

  1. 将本地 @vue/cli-xxx 依赖项升级到您主要版本范围内的最新版本(如果适用)

    • ~4.5.18 for v4
    • ~5.0.6 for v5
  2. vue 升级到 ^2.7.0。您也可以从依赖项中删除 vue-template-compiler - 它在 2.7 中不再需要。

    注意:如果您使用的是 @vue/test-utils,则需要在依赖项中保留 vue-template-compiler,因为测试工具依赖于仅在此包中公开的某些 API。

  3. 检查您的包管理器锁定文件,以确保以下依赖项满足版本要求。它们可能是 package.json 中未列出的传递依赖项。

    • vue-loader: ^15.10.0
    • vue-demi: ^0.13.1

    如果没有,您将需要删除 node_modules 和锁定文件,并执行全新安装以确保它们被提升到最新版本。

  4. 如果您之前使用的是 @vue/composition-api,请将来自它的导入更新为 vue。请注意,插件导出的某些 API(例如 createApp)在 2.7 中没有移植。

  5. 如果您在使用 <script setup> 时遇到未使用的变量 lint 错误,请将 eslint-plugin-vue 更新到最新版本(9+)。

  6. 2.7 的 SFC 编译器现在使用 PostCSS 8(从 7 升级)。PostCSS 8 应该与大多数插件向后兼容,但如果之前使用的是只能与 PostCSS 7 一起使用的自定义 PostCSS 插件,则升级可能会导致问题。在这种情况下,您需要将相关插件升级到其与 PostCSS 8 兼容的版本。

Vite

2.7 对 Vite 的支持是通过一个新的插件提供的:@vitejs/plugin-vue2。这个新插件需要 Vue 2.7 或更高版本,并且取代了现有的 vite-plugin-vue2

请注意,新插件不处理特定于 Vue 的 JSX/TSX 转换,这是故意的。Vue 2 JSX/TSX 转换用于 Vite 在一个单独的专用插件中处理:@vitejs/plugin-vue2-jsx

Volar 兼容性

2.7 附带改进的类型定义,因此不再需要安装 @vue/runtime-dom 仅用于 Volar 模板类型推断支持。您现在只需要在 tsconfig.json 中配置以下内容

json
{
  // ...
  "vueCompilerOptions": {
    "target": 2.7
  }
}

Devtools 支持

Vue Devtools 6.2.0 已添加对检查 2.7 组合式 API 状态的支持,但扩展程序可能还需要几天时间才能通过各自发布平台上的审查。

2.7 版本的影响

如前所述,2.7 是 Vue 2.x 的最后一个次要版本。在此版本之后,Vue 2 已进入 LTS(长期支持),从现在开始持续 18 个月,并且将不再接收新功能。这意味着Vue 2 将于 2023 年 12 月 31 日结束生命周期

我们相信这应该为大多数生态系统迁移到 Vue 3 提供充足的时间。但是,我们也了解到可能有一些团队或项目无法在该时间表之前升级,同时仍需要满足安全和合规性要求。我们正在与行业专家合作,为有此类需求的团队提供 Vue 2 的扩展支持 - 如果您的团队预计在 2023 年底之后使用 Vue 2,请务必提前计划并详细了解 Vue 2 扩展 LTS

额外细节

为了准备这次发布,我们将 Vue 2 代码库从 Flow 移植到 TypeScript,这是基于核心团队成员 @pikax 的英勇努力。这让我们更容易重用 Vue 3 的代码,并自动生成移植 API 的类型定义。我们还将单元测试从 Karma + Jasmine 迁移到 Vitest,从而极大地提高了维护 DX 和 CI 稳定性。

我们还要感谢之前社区的努力,他们在 2.7 可用之前弥合了差距