创建日期:2026-09-08 | 最近更新:2026-09-08 版本基线:Vue 3.5.42(npm 当前 latest;3.6 仍处 RC)。Vue 2 最终版 2.7.16,OSS 支持已于 2023-12-31 结束。
Vue2 → Vue3 快车道:给熟练 Vue2 开发的心智迁移清单
一句话:Vue 3 不是「另一个框架」,它是把 Vue 2 里你用惯的那套「魔法」换成了更显式的引擎——你会的 80% 直接平移,剩下 20% 是「全局 API 变成 app 实例、Options 换成可组合函数、响应式底层换成 Proxy」。这篇不教语法,只帮你把「旧脑图」一次性迁移过来。
本系列面向熟练 Vue2、想最短路径上 Vue3 并进阶的开发者,共 6 篇:
| 篇 | 主题 | 深度 |
|---|---|---|
| 0 | 快车道:心智迁移清单 + 上手路线(本文) | 导览 |
| 1 | Composition API 与 script setup:ref/reactive/computed/watch、defineProps/defineEmits/defineModel | 中 |
| 2 | 迁移深水区:过滤器/$set/fragments/异步组件/Teleport·Suspense/Vuex→Pinia·Router3→4 | 深(实操) |
| 3 | 深 · Vue3 响应式系统拆解:Proxy vs defineProperty、effect、ref 的 .value 真相 | 深(原理) |
| 4 | 深 · 模板编译与渲染优化:Block/patchFlags/静态提升/v-once/v-memo | 深(原理) |
| 5 | 组合式进阶 × TypeScript × 工程化:composable 范式、Pinia setup store、Router、Vite | 中上 |
1. 心智模型:Vue 3 = Vue 2 的三个「换底」
对 Vue2 熟手,与其背 API,不如记住三处换底,其余全是平移:
- 入口换底:
new Vue(...)+ 全局Vue.*→createApp(...)+ app 实例。所有「全局」注册都收编到 app 上,好处是多实例/微前端/测试不再互相污染。 - 代码组织换底:
data/methods/computed/watch各占一块的 Options → 一个setup(或<script setup>)里用函数拼。组件状态从「对象字段」变成「函数调用」,天然可抽出复用(篇 1、5)。 - 响应式换底:
Object.defineProperty逐属性劫持 → ESProxy整对象代理。所以你不再需要this.$set/Vue.set/Vue.delete——后加属性、数组下标赋值直接就能响应(篇 3 拆原理)。
对「精通 Vue2」的你:真正要改习惯的只有 API 形状;概念(响应式、组件、指令、插槽、混入→组合式函数)全都一样。
2. 三张「旧→新」对照表(先背这三张,代码就能读了)
① 全局 API / 实例
| Vue 2 | Vue 3 | 说明 |
|---|---|---|
new Vue({ el:'#app', ... }) | createApp(App).mount('#app') | 组件树挂载 |
Vue.component(name, comp) | app.component(name, comp) | 局部注册更推荐 |
Vue.use(plugin, opts) | app.use(plugin, opts) | 插件都要带 app |
Vue.directive / mixin / filter | app.directive / app.mixin / 无 | filter 没了(见下) |
Vue.prototype.$http = … | app.config.globalProperties.$http = … | 全局注入改这里 |
this.$set / this.$delete / Vue.set | 不需要了 | Proxy 原生支持增删属性 |
this.$children / $scopedSlots / $listeners | 移除 | $attrs 吸收 $listeners;$slots 合并 |
this.$on/$off/$emit(非父子) | 移除(用 mitt) | 事件总线不再是内置 |
this.$refs / $nextTick / $watch(...) | 都在,$nextTick 也可 import { nextTick } | 组合式里 watch 是函数 |
② 组件写法(最重要的一行差异)
// Vue 2
export default {
name: 'Counter',
props: ['init'],
data() { return { count: this.init } },
computed: { double() { return this.count * 2 } },
methods: { inc() { this.count++ } },
watch: { count(v) { console.log('count', v) } },
mounted() { console.log('mounted') },
}
<!-- Vue 3 · <script setup>(推荐写法,下面等价) -->
<script setup>
import { ref, computed, watch, onMounted } from 'vue'
const props = defineProps({ init: Number }) // props 仍声明式
const count = ref(props.init) // data → ref
const double = computed(() => count.value * 2) // computed 变函数
function inc() { count.value++ } // methods → 普通函数
watch(count, v => console.log('count', v))
onMounted(() => console.log('mounted'))
</script>
| Vue 2 (Options) | Vue 3 (Composition / script setup) |
|---|---|
data() | ref() / reactive() |
computed: {} | computed(() => …) |
methods: {} | 普通函数 |
watch: {} | watch(src, cb) |
props 选项 | defineProps() |
$emit | defineEmits() |
生命周期 mounted/… | onMounted/…(在 <script setup> 里直接用) |
mixins | 组合式函数(useXxx(),篇 5 重点) |
③ 模板/全局差异速查
| 项 | Vue 2 | Vue 3 |
|---|---|---|
过滤器 {{ x | fmt }} / filters: | ✅ | ❌ 移除 → 用 computed/方法或 $filters(全局属性) |
v-model 默认 prop | value + input | modelValue + update:modelValue;支持多个 v-model:title、v-model:title 等 |
.sync 修饰符 | :a.sync | 并入多 v-model(v-model:a),.sync 移除 |
v-model 带 $event | 事件值在 $event | 值直接是回调参数(组件 emit 的第一个参数) |
.native 修饰符 | @click.native | 移除 → 组件根节点事件默认透传($attrs) |
| 多根节点 | 必须单根 | 支持 fragment(但要手动绑定 $attrs 到想要的那个根) |
v-if / v-for 优先级 | v-for 高 | v-if 高(同元素别混用,包 template) |
| 异步组件 | () => import() 直接 | defineAsyncComponent(() => import()) |
<Portal> | 靠插件 | 内置 <Teleport> |
顶层 $slots | this.$scopedSlots | $slots(函数式 slot 语法,篇 1/2) |
3. 三天上手路线(对 Vue2 熟练者)
- 第 1 天:手写平移。 挑一个自己最熟的小组件,用上面②表把它从 Options 改成
<script setup>;再挑一个用到了$set/过滤器/.sync/事件总线的,看报错清单学会「新 API 在哪」。遇到报错别慌,Vue 3 的告警通常直接告诉你换什么。 - 第 2 天:补新武器。 过一遍 篇 1:
defineModel、defineExpose、provide/inject配合、组合式函数怎么抽。再翻 篇 2 的逐项清单。 - 第 3 天:吃透原理。 读 篇 3 与 篇 4(有实验输出),把「为什么不用 $set、为什么列表性能好」从「记住」变「理解」。
想先摸手感:
npm create vue@latest选好模板,或看官方交互教程 Vue 3 playground。国内可先vuejs.cn。
4. 开始前想清楚的一件事
要不要保留 Options API? Vue 3 两种都能写,但新代码请直接上 <script setup>:
- 它是官方推荐、类型推导最好、样板最少;
- Options 写法在 Vue 3 依旧可用,适合渐进迁移期(老组件不动),但别用 Options + mixins 继续写新东西——那等于放弃 Composition 最大的红利(复用与类型)。
迁移节奏建议:从老 Vue2 项目「底朝上」升级先别急——先在新页面/新需求里用 Composition 写,积累手感;真正动老组件时用官方升级工具(vue-router、Vue 官方「Migrate」工具与 迁移指南)辅助。
关联
- 下一篇:Composition API 与 script setup
- 工具链上下文:Maven、Spring(本码列「脚手架+分层」的对照视角)——Vue3 + Vite 的工程化在篇 5
参考
- 官方迁移指南(逐条 API 对照):v3-migration.vuejs.org
- Vue 3 文档:cn.vuejs.org
- 在线试:play.vuejs.org
- 本文基于 Vue 3.5.42 / Vue 2.7.16(2026-09)核对;新功能以官方文档为准。