Vue2转Vue3速查表

1. 核心语法结构对比

Vue 2 (Options API) Vue 3 (<script setup>) 说明
模板 模板 模板语法基本不变 (v-if, v-for, v-model)
html<br><template><div>{``{ count }}</div></template><br><script><br>export default {<br> data() { return { count: 0 } },<br> methods: { inc() { this.count++ } }<br>}<br></script> html<br><template><div>{``{ count }}</div></template><br><script setup><br>import { ref } from 'vue'<br>const count = ref(0)<br>const inc = () => count.value++<br></script> <script setup> 是语法糖,无需 export default,顶层变量自动暴露给模板。
this 指向 无 this Vue 2 依赖 this;Vue 3 直接访问变量,更清晰。

2. 响应式数据 (Reactivity)

不再区分 data, props, computed 的写法,统一用函数。

概念 Vue 2 Vue 3 (Composition API) 注意事项
基础类型 (string, number) data() { return { count: 0 } } 使用:this.count const count = ref(0) 使用 (JS): count.value 使用 (模板): {``{ count }} 重点: JS 中访问 ref 必须加 .value,模板中自动解包。
对象/数组 data() { return { user: {} } } 方式 A: const user = ref({}) (需 .value) 方式 B: const user = reactive({}) (无需 .value) 推荐: 优先用 ref 保持一致性;若对象层级深且频繁修改,可用 reactive。
计算属性 computed: { double() { return this.count * 2 } } const double = computed(() => count.value * 2) 只读。若要写值:computed({ get: ()=>..., set: (v)=>... })
监听器 watch: { count(val) { ... } } watch(count, (newVal, oldVal) => { ... }) 监听多个:watch([a, b], ...) watch 第一个参数可以是 ref 或 getter 函数 () => obj.prop。
深度监听 watch: { user: { handler, deep: true } } watch(user, ..., { deep: true }) 若用 reactive 默认开启深度。

3. 生命周期 (Lifecycle Hooks)

钩子函数名称改变,需要导入 并在 setup 中调用。

阶段 Vue 2 Vue 3 (导入自 'vue') 说明
创建前 beforeCreate ❌ 不需要 setup() 本身就是初始化逻辑
创建后 created ❌ 不需要 在 setup() 中直接写代码即可
挂载前 beforeMount onBeforeMount
挂载后 mounted onMounted 常用:操作 DOM, 发起请求
更新前 beforeUpdate onBeforeUpdate
更新后 updated onUpdated
卸载前 beforeDestroy onBeforeUnmount ⚠️ 名字变了 (Destroy -> Unmount)
卸载后 destroyed onUnmounted ⚠️ 名字变了
错误捕获 errorCaptured onErrorCaptured
示例:
javascript 复制代码
// Vue 2
mounted() { console.log('mounted') }

// Vue 3
import { onMounted } from 'vue'
onMounted(() => {
  console.log('mounted')
})

4. 组件通信 (Props & Emits)

功能 Vue 2 Vue 3 (<script setup>) 说明
接收 Props props: ['title'] 使用:this.title const props = defineProps(['title']) 使用:props.title defineProps 无需导入,编译器宏。
定义 Emits emits: ['update'] 触发:this.$emit('update') const emit = defineEmits(['update']) 触发:emit('update') defineEmits 无需导入。
双向绑定 v-model="val" (默认) v-model="val" (默认 prop: modelValue, event: update:modelValue) Vue 3 移除了 .sync,统一用 v-model:propName。
多 v-model 不支持 (需用 .sync 变通) <Comp v-model:title="t" v-model:count="c" /> 父组件可绑定多个模型。

5. 插槽 (Slots) 与 refs

功能 Vue 2 Vue 3 (<script setup>) 说明
默认插槽 <slot></slot> <slot></slot> 模板用法不变
具名插槽 <slot name="header"></slot> <slot name="header"></slot>
作用域插槽 <template v-slot:default="slotProps"> <template #default="{ item }"> # 是 v-slot: 的简写 (Vue 2.6+ 已有,Vue 3 推荐)
获取子组件实例 this.$refs.child const child = ref(null) <Child ref="child" /> 重大变化: ref 现在是响应式变量,需绑定到 template 的 ref 属性。访问时用 child.value。
获取 DOM 元素 this.$refs.input const input = ref(null) <input ref="input" /> 同上,统一用 ref()。

6. 全局 API 与 内置组件变化

Vue 2 Vue 3 说明
Vue.use(Plugin) app.use(Plugin) 必须通过 createApp 实例调用
Vue.component(...) app.component(...)
Vue.directive(...) app.directive(...)
new Vue({ ... }) createApp({ ... }) 入口变了
<transition> <transition> 类名变化:v-enter -> v-enter-from, v-leave -> v-leave-from
<transition-group> <transition-group> 同上
v-on:click @click 简写依旧支持
keyCode 修饰符 ❌ 已移除 必须使用 key 别名 (如 .enter) 或检查 event.key
$children ❌ 已移除 使用 ref 或 provide/inject 替代
$listeners ❌ 已移除 所有监听器都合并到 $attrs 中,自动透传

7. 状态管理 (Vuex -> Pinia)

Vue 3 官方推荐 Pinia 替代 Vuex。

概念 Vuex (Vue 2) Pinia (Vue 3) 优势
定义 Store new Vuex.Store({ state, mutations, actions }) defineStore('id', { state, actions, getters }) 去掉了 mutations,只有 state/getters/actions。
读取 State this.$store.state.count store.count 像访问普通对象属性一样。
修改 State this.$store.commit('inc') store.count++ 或 store.inc() 直接修改或调用 action,更直观。
映射辅助函数 mapState, mapActions 不需要!直接解构 (需注意 storeToRefs) 代码更少。
TypeScript 支持较差,需复杂泛型 原生完美支持 TS 自动推断类型。
Pinia 示例:
javascript 复制代码
// stores/counter.ts
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() { this.count++ } // 直接用 this
  }
})

// 组件中使用
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
store.increment()
console.log(store.count)

8. 常见迁移陷阱 (Pitfalls)

  1. Ref 的 .value :
    • 在 <script> 里忘记加 .value 是最常见的错误。
    • 口诀: "模板里直接用,脚本里加点值"。
  2. Reactive 的解构丢失响应性 :
    • const { name } = reactive(user) -> name 失去响应性。
    • 解决 : 使用 toRefs(user) 或直接用 user.name。
  3. Watch 的第一个参数 :
    • 如果监听 reactive 对象的某个属性,必须用 getter: watch(() => obj.prop, ...)。
    • 如果直接传 obj.prop (值),它不会响应变化。
  4. Provide / Inject :
    • Vue 2: provide: { key: value }
    • Vue 3: provide('key', value) 和 inject('key', defaultValue) 函数。
  5. 异步组件 :
    • Vue 2: () => import('./Comp.vue')
    • Vue 3: defineAsyncComponent(() => import('./Comp.vue'))

9. 快速迁移步骤

  1. 升级依赖 : npm install vue@latest
  2. 全局搜索替换 :
    • beforeDestroy -> onBeforeUnmount
    • destroyed -> onUnmounted
    • $children -> 重构为 ref 列表
  3. 转换单文件组件 (SFC) :
    • 将 <script> 改为 <script setup lang="ts"> (推荐直接上 TS)。
    • 把 data 转为 ref/reactive。
    • 把 methods 转为普通函数。
    • 把 computed 转为 computed()。
    • 把 watch 转为 watch()。
    • 把 props/emits 转为 defineProps/defineEmits。
  4. 状态管理: 逐步将 Vuex 模块迁移到 Pinia。

总结 : Vue 3 的核心思想是**"逻辑复用"** 。以前靠 Mixins (有命名冲突风险),现在靠 Composables (组合式函数) (如 useMouse, useFetch)。

这是 Vue 3 最强大的特性,建议在学习基础语法后,立即学习如何编写 Composables。

https://cn.vuejs.org/

相关推荐
不停喝水5 分钟前
【前端转全栈java速通课】 项目实战④-1 Spring Boot 创建项目-定义接口-请求参数处理-分层规范-依赖注入
java·前端·spring boot
用户298698530146 分钟前
在 React 中使用 JavaScript 将 HTML 转换为 PDF
javascript·react.js·html
OpsEye14 分钟前
企业如何统一管理多家大模型 API?
javascript·ai编程
涛涛ing15 分钟前
当AI能写原生代码:Shopify用12周把React Native应用迁回了Swift和Kotlin
前端
JudithHuang24 分钟前
React 数据请求:TanStack Query
前端·react.js·前端框架
程序员-Benothing28 分钟前
Shell脚本入门教程:Shebang、变量、注释与执行方式
前端·chrome
java_nnnn33 分钟前
JavaEE进阶-JavaScript初识
开发语言·前端·javascript·java-ee·ecmascript
裕晟资质规划1 小时前
涉密场所物理隔离与技术防护体系:标准矩阵、审查校验点与常见缺陷分析
大数据·前端·网络·人工智能·经验分享
变与不变8061 小时前
JSON基础详解
前端·javascript
吴声子夜歌1 小时前
HTML——结构化微数据语言简介
前端·数据库·html