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 ❌ 已移除 使用 refprovide/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/

相关推荐
紫_龙2 小时前
最新版vue3+TypeScript开发入门到实战教程之toRefs与toRef实用技巧
前端·javascript·typescript
大家的林语冰2 小时前
Vite 第 1 个 Rolldown 稳定版正式发布,前端构建又一波“工业革命“
前端·javascript·vite
博客zhu虎康2 小时前
我的创作纪念日——五载创作路,以技术赴热爱
前端·经验分享·csdn·技术分享·我的创作纪念日
前端之虎陈随易3 小时前
Vite 8正式发布,内置devtool,Wasm SSR 支持
前端·人工智能·typescript·npm·node.js·wasm
AI_56783 小时前
基于智优达平台的Python教学实践:从环境搭建到自动评测
开发语言·前端·人工智能·后端·python
IT_陈寒3 小时前
JavaScript开发者必备的5个高效调试技巧,90%的人都不知道最后一个!
前端·人工智能·后端
嘉琪0013 小时前
前端数组核心方法(高级视角 + 场景 + 精简)——————2026 0309
开发语言·前端·javascript
jarvisuni4 小时前
GLM5实战测试,挑战Opus4.6 !
前端·数据库
颜酱4 小时前
二分图核心原理与判定算法
javascript·后端·算法