Vue 3.6 Vapor 在 Nuxt 4.6 只能 interop:开启方式、限制清单与实测数字
Vue Vapor Mode 是 3.6 版本里最受关注的特性:一种编译模式,编译时跳过 Virtual DOM,生成直接更新 DOM 的代码。它是 opt-in 的,不需要重写整个应用,可以按组件选择哪些用 Vapor 编译。Vue 3.6 本身还没稳定,在 Nuxt 里也只能以 interop 形式接入——应用根仍然跑在 Virtual DOM 上。
版本前提
截至 2026-10-06,Vue 最新版本是 3.6.0-rc.10(9/30 发布),稳定版仍是 3.5.43(9/17)。之后 10/23 发了 3.6.0-rc.13,10/30 发了 3.6.0-rc.14。也就是说,想用 Vapor,得先接受 RC 版本。
Nuxt 这边,Nuxt 3 已于 2026-07-31 EOL。
Nuxt 之外的 Vapor 编译
不用 Nuxt 时,由 @vitejs/plugin-vue 编译 Vapor SFC。插件 changelog 里记录了 Vapor 组件支持,包括只有模板的组件,所以需要选用较新的插件版本。
Nuxt 4.6 里的 interop 模式
Nuxt 4.6(2026-10-05 发布)以 interop 模式支持 Vapor:应用根仍在 Virtual DOM 上,你选择哪些组件或页面用 Vapor 编译。
开启方式是在 nuxt.config.ts 里打开选项:
export default defineNuxtConfig({
vue: {
vapor: true,
},
})
然后在组件上标记。官方文档写作在 `` 上加 vapor 属性。
版本要求:Nuxt 要求 Vue ^3.6.0-rc.2 或更新。
按发布说明,路由、useAsyncData、layouts 和大多数内置组件保持原样工作。发布说明也建议先在全新项目里试,而不是直接往存量项目上套。
interop 模式的限制
Nuxt 文档列出的限制如下:
- 应用根不能是 Vapor,因为 Nuxt 里没有完全 Vapor 的应用;
- Vapor 组件在 template ref 上不暴露
$el; - 某个内置组件会跳过属性透传;
NuxtIsland/ServerComponent与读取文本子节点的 head 组件(Title、Description 等)在传入 Vapor slot 时会告警; - keyed
onPrehydrate回退成非 keyed 形式(并在开发环境告警),因为没有组件实例可以挂 key; - 通过
defineNuxtComponent使用asyncData与fetchKey不工作,改用 `` 里的useAsyncData; - 在
await之后调用 Nuxt composables 可能丢失上下文。
这份清单基本决定了迁移成本落在哪里:碰到 template ref 取 $el、NuxtIsland、head 组件的 slot、或者 defineNuxtComponent 的 asyncData,就得改代码或者把对应组件留在 VDOM 路径上。
性能数字
Nuxt 4.6 发布说明给了 starter 项目的数据:
nuxt build从 4.4 s 到 3.6 s,快 18%;- 含 300 个某类组件的页面,SSR 从 110 到 140 req/s,+26%。
需要注意,Nuxt 把这些收益归因于该版本的通用优化,而不是 Vapor。也就是说这组数字不能直接当作“开 Vapor 的收益”来读。
什么时候值得试
按发布说明的建议,全新项目是最省事的起点:没有存量代码去撞 template ref、defineNuxtComponent 这些限制,开启 vue.vapor 后按组件加 vapor 属性,逐个观察。
存量项目则先看限制清单里有没有命中项——用到 NuxtIsland、head 组件的文本子节点 slot、onPrehydrate 的 keyed 形式,或者依赖 defineNuxtComponent 的 asyncData / fetchKey,都需要先改造或把这些组件排除在 Vapor 之外。另外 Nuxt 4.6 的构建与 SSR 数字来自通用优化,不是 Vapor 的收益,评估时不要把这部分算进去。
最后是版本:Vue 3.6 仍在 RC,Nuxt 3 已 EOL,当前能在 Nuxt 里跑 Vapor 的组合是 Nuxt 4.6 + Vue ^3.6.0-rc.2。