Vue3 与 Vue2 核心差异:响应式原理、生命周期及迁移方案

Vue3 与 Vue2 核心差异:响应式原理、生命周期及迁移方案


总览:为什么升级到 Vue3

  • 性能:编译时优化(静态提升、Patch Flags、缓存事件处理),初始化与更新更快
  • 体积与可维护:模块化与 Tree-Shaking,按需引入核心能力
  • 类型与工程:原生 TypeScript 支持、Composition API 提升代码组织与复用
  • 能力扩展:Teleport、Suspense、Fragments、Multi-root、异步组件更友好

响应式原理差异

  • Vue2:Object.defineProperty 拦截对象属性读取/设置,数组通过原型方法劫持;无法直接监听新增/删除属性,需 Vue.set/ Vue.delete
  • Vue3:Proxy 拦截对象/数组/Map/Set 等结构,配合 track/trigger 精细依赖收集与更新
js 复制代码
// Vue2 思路(简化):
function defineReactive(obj, key) {
  let val = obj[key]
  Object.defineProperty(obj, key, {
    get() { /* 依赖收集 */ return val },
    set(nv) { if (nv !== val) { val = nv; /* 派发更新 */ } }
  })
}

// Vue3 思路(简化):
const reactive = (target) => new Proxy(target, {
  get(t, k, r) { /* track(t,k) */ return Reflect.get(t, k, r) },
  set(t, k, v, r) { const ok = Reflect.set(t, k, v, r); /* trigger(t,k) */ return ok }
})
  • Vue3 响应式 API:reactive(对象代理)、ref(值容器)、computed(派生)、watch/watchEffect(副作用)、shallowRef/shallowReactivemarkRaw/toRaw
  • 变更点:
    • 不再需要 Vue.set,可直接新增属性并触发更新
    • ref 在模板自动解包,脚本需 .value
    • Map/Set 等原生结构可响应

细节对比:

  • 依赖收集精度:Vue3 基于 effect 栈与 targetMap,按 key 维度收集;Vue2 以对象级别收集,数组依赖粗粒度
  • 性能:Vue3 静态提升与 Patch Flags 减少遍历与 diff;Vue2 运行时比对更重
  • 数据结构:Vue3 支持 WeakMap/Map/Set 代理;Vue2 仅对象/数组可观测

生命周期映射与差异

  • Vue2 Options:beforeCreate/created/mounted/updated/destroyed
  • Vue3 Composition:以 setup 为入口,onMounted/onUpdated/onUnmounted 等组合式钩子
txt 复制代码
Vue2 → Vue3 对照:
- beforeCreate/created → setup(初始化)
- beforeMount/mounted → onBeforeMount/onMounted
- beforeUpdate/updated → onBeforeUpdate/onUpdated
- beforeDestroy/destroyed → onBeforeUnmount/onUnmounted
- activated/deactivated → onActivated/onDeactivated(KeepAlive)
  • 渲染入口:Vue2 使用 new Vue({ el, render }),Vue3 使用 createApp(App).mount('#app')
  • 模板:Vue3 支持多根节点与 Fragment;$listeners/$scopedSlots 合并为统一 slotsemits

指令钩子映射:

复制代码
bind → beforeMount
inserted → mounted
update → updated
componentUpdated → updated(或结合 onUpdated)
unbind → unmounted

语法与 API 差异(高频)

  • v-model:
    • Vue2:v-model 语法糖=value+input
    • Vue3:默认 modelValue + update:modelValue,支持多 v-model:prop
  • 过滤器(filters):移除,改为计算属性/方法
  • 全局 API:
    • Vue2:Vue.use/ Vue.mixin/ Vue.component
    • Vue3:实例化后通过 app.use/ app.mixin/ app.component
  • 插槽:作用域插槽统一为 slots,无需 slot-scope
  • 自定义指令:钩子更名(bindbeforeMountinsertedmounted

多模型 v-model 示例:

vue 复制代码
<Child v-model:visible="show" v-model:title="title" />
ts 复制代码
// 子组件
const props = defineProps<{ visible: boolean; title: string }>()
const emit = defineEmits<{ (e:'update:visible', v:boolean):void; (e:'update:title', v:string):void }>()

迁移方案(增量落地)

  • 依赖与兼容:
    • 使用 @vue/compat(迁移构建)在 Vue3 上运行 Vue2 代码,观察兼容警告并逐项修复
    • 升级生态:Vue Router v4、Pinia(或保留 Vuex 4)、Vite 构建
  • 组件改造路径:
    • filters → 函数/计算属性
    • v-modelmodelValue/update:modelValue(必要时支持多模型)
    • $listeners/$scopedSlotsemits/slots
    • mixins → 组合式函数(Composables),避免隐式依赖与命名冲突
  • 响应式修正:
    • 取消 Vue.set/delete,直接修改对象属性即可响应
    • 对深数据结构采用 reactive,基础类型用 ref
  • 生命周期重映射:将 created 初始化逻辑迁入 setup;副作用统一收敛到 onMounted/onUnmountedwatch

兼容构建使用:

js 复制代码
// vue.config.js 或构建配置中启用 @vue/compat
module.exports = { configureWebpack: { resolve: { alias: { 'vue': '@vue/compat' } } } }

在运行时观察兼容警告,逐项替换到 Vue3 API。

示例:Options API → Composition API

Vue2:

js 复制代码
export default {
  data() { return { count: 0 } },
  computed: { double() { return this.count * 2 } },
  created() { this.init() },
  methods: { init() {}, inc() { this.count++ } }
}

Vue3:

ts 复制代码
import { ref, computed, onMounted } from 'vue'
export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    const inc = () => { count.value++ }
    onMounted(() => init())
    function init() {}
    return { count, double, inc }
  }
}

过滤器迁移示例:

Vue2:

vue 复制代码
<span>{{ price | currency }}</span>

Vue3:

vue 复制代码
<script setup>
const currency = (n:number) => new Intl.NumberFormat('zh-CN', { style:'currency', currency:'CNY' }).format(n)
</script>
<span>{{ currency(price) }}</span>

Mixin → Composable:

Vue2 Mixin:

js 复制代码
export const userMixin = { created(){ this.fetchUser() }, methods:{ fetchUser(){ /*...*/ } } }

Vue3 Composable:

ts 复制代码
import { ref, onMounted } from 'vue'
export function useUser(){ const user = ref(null); onMounted(async()=>{ user.value = await fetchUser() }); return { user } }

工程化与生态替换

  • 构建:推荐 Vite,配合 unplugin-auto-import/unplugin-vue-components 按需引入
  • 路由:Vue Router v4 的组合式导航守卫与动态路由
  • 状态:Pinia 替代 Vuex,类型推断更友好,Action/Getter 更简化
  • DevTools:Vue3 Devtools 支持组件树、响应式追踪与性能面板

Vuex → Pinia 映射:

复制代码
state → state()
getters → getters
mutations/actions → actions(无需区分)
modules → 多 store + 组合式复用

性能与可维护性提升点

  • 编译时优化:静态节点提升、指令与属性打标,减少运行时比较开销
  • 事件缓存与 v-once/v-memo:降低重复绑定成本
  • 多根/Fragment:减少不必要的包裹元素,简化结构

编译优化说明:

  • 静态提升:模板中不变节点移出渲染函数缓存
  • Patch Flags:为动态节点打标(如 CLASS/PROPS/TEXT),运行时精准比对
  • 事件缓存:重复事件绑定存储与复用,降低创建成本

微基准建议:

  • 渲染 1k 列表对比 CSR(Vue2)与 Vue3 静态提升,记录渲染时长与内存占用

迁移检查清单

  • 全局 API 改为 app.xxx,插件通过 app.use
  • 移除 filters,替换为方法/计算
  • 统一插槽与事件:emits 显式声明事件,校验参数
  • v-model 改造为 modelValue/update:modelValue,必要时支持多 v-model:prop
  • 指令钩子更名与依赖修正(遇到 DOM 依赖逻辑用 onMounted
  • Mixins 清理与合并到组合式函数;抽象副作用为可停止的 Hooks

Router 迁移提示:

  • Vue Router v3 的导航守卫(beforeRouteEnter)迁移为 v4 组合式 onBeforeRouteUpdate 或全局守卫;动态路由改用 useRoute/useRouter

常见坑与修复

  • setup 访问 this(无实例):用返回对象或 getCurrentInstance
  • 深层响应式误用:基础类型用 ref,对象用 reactive;避免对 reactive 顶层整体替换
  • watch 触发过多:监听具体 getter 或 toRef;需要深度时再加 { deep: true }
  • v-model 不生效:对齐子组件 modelValueupdate:modelValue 协议

总结

  • Vue3 在性能、类型与工程化方面显著优于 Vue2,核心差异集中在响应式原理与生命周期映射
  • 迁移以增量方式进行:先兼容运行,逐项替换 API 与模式,再落地 Composition API 与生态升级
  • 借助工具链与编译优化,项目可得到更好的可维护性与长期演进空间

Vue3 与 Vue2 核心差异:响应式原理、生命周期及迁移方案


总览:为什么升级到 Vue3

  • 性能:编译时优化(静态提升、Patch Flags、缓存事件处理),初始化与更新更快
  • 体积与可维护:模块化与 Tree-Shaking,按需引入核心能力
  • 类型与工程:原生 TypeScript 支持、Composition API 提升代码组织与复用
  • 能力扩展:Teleport、Suspense、Fragments、Multi-root、异步组件更友好

响应式原理差异

  • Vue2:Object.defineProperty 拦截对象属性读取/设置,数组通过原型方法劫持;无法直接监听新增/删除属性,需 Vue.set/ Vue.delete
  • Vue3:Proxy 拦截对象/数组/Map/Set 等结构,配合 track/trigger 精细依赖收集与更新
js 复制代码
// Vue2 思路(简化):
function defineReactive(obj, key) {
  let val = obj[key]
  Object.defineProperty(obj, key, {
    get() { /* 依赖收集 */ return val },
    set(nv) { if (nv !== val) { val = nv; /* 派发更新 */ } }
  })
}

// Vue3 思路(简化):
const reactive = (target) => new Proxy(target, {
  get(t, k, r) { /* track(t,k) */ return Reflect.get(t, k, r) },
  set(t, k, v, r) { const ok = Reflect.set(t, k, v, r); /* trigger(t,k) */ return ok }
})
  • Vue3 响应式 API:reactive(对象代理)、ref(值容器)、computed(派生)、watch/watchEffect(副作用)、shallowRef/shallowReactivemarkRaw/toRaw
  • 变更点:
    • 不再需要 Vue.set,可直接新增属性并触发更新
    • ref 在模板自动解包,脚本需 .value
    • Map/Set 等原生结构可响应

细节对比:

  • 依赖收集精度:Vue3 基于 effect 栈与 targetMap,按 key 维度收集;Vue2 以对象级别收集,数组依赖粗粒度
  • 性能:Vue3 静态提升与 Patch Flags 减少遍历与 diff;Vue2 运行时比对更重
  • 数据结构:Vue3 支持 WeakMap/Map/Set 代理;Vue2 仅对象/数组可观测

生命周期映射与差异

  • Vue2 Options:beforeCreate/created/mounted/updated/destroyed
  • Vue3 Composition:以 setup 为入口,onMounted/onUpdated/onUnmounted 等组合式钩子
txt 复制代码
Vue2 → Vue3 对照:
- beforeCreate/created → setup(初始化)
- beforeMount/mounted → onBeforeMount/onMounted
- beforeUpdate/updated → onBeforeUpdate/onUpdated
- beforeDestroy/destroyed → onBeforeUnmount/onUnmounted
- activated/deactivated → onActivated/onDeactivated(KeepAlive)
  • 渲染入口:Vue2 使用 new Vue({ el, render }),Vue3 使用 createApp(App).mount('#app')
  • 模板:Vue3 支持多根节点与 Fragment;$listeners/$scopedSlots 合并为统一 slotsemits

指令钩子映射:

复制代码
bind → beforeMount
inserted → mounted
update → updated
componentUpdated → updated(或结合 onUpdated)
unbind → unmounted

语法与 API 差异(高频)

  • v-model:
    • Vue2:v-model 语法糖=value+input
    • Vue3:默认 modelValue + update:modelValue,支持多 v-model:prop
  • 过滤器(filters):移除,改为计算属性/方法
  • 全局 API:
    • Vue2:Vue.use/ Vue.mixin/ Vue.component
    • Vue3:实例化后通过 app.use/ app.mixin/ app.component
  • 插槽:作用域插槽统一为 slots,无需 slot-scope
  • 自定义指令:钩子更名(bindbeforeMountinsertedmounted

多模型 v-model 示例:

vue 复制代码
<Child v-model:visible="show" v-model:title="title" />
ts 复制代码
// 子组件
const props = defineProps<{ visible: boolean; title: string }>()
const emit = defineEmits<{ (e:'update:visible', v:boolean):void; (e:'update:title', v:string):void }>()

迁移方案(增量落地)

  • 依赖与兼容:
    • 使用 @vue/compat(迁移构建)在 Vue3 上运行 Vue2 代码,观察兼容警告并逐项修复
    • 升级生态:Vue Router v4、Pinia(或保留 Vuex 4)、Vite 构建
  • 组件改造路径:
    • filters → 函数/计算属性
    • v-modelmodelValue/update:modelValue(必要时支持多模型)
    • $listeners/$scopedSlotsemits/slots
    • mixins → 组合式函数(Composables),避免隐式依赖与命名冲突
  • 响应式修正:
    • 取消 Vue.set/delete,直接修改对象属性即可响应
    • 对深数据结构采用 reactive,基础类型用 ref
  • 生命周期重映射:将 created 初始化逻辑迁入 setup;副作用统一收敛到 onMounted/onUnmountedwatch

兼容构建使用:

js 复制代码
// vue.config.js 或构建配置中启用 @vue/compat
module.exports = { configureWebpack: { resolve: { alias: { 'vue': '@vue/compat' } } } }

在运行时观察兼容警告,逐项替换到 Vue3 API。

示例:Options API → Composition API

Vue2:

js 复制代码
export default {
  data() { return { count: 0 } },
  computed: { double() { return this.count * 2 } },
  created() { this.init() },
  methods: { init() {}, inc() { this.count++ } }
}

Vue3:

ts 复制代码
import { ref, computed, onMounted } from 'vue'
export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    const inc = () => { count.value++ }
    onMounted(() => init())
    function init() {}
    return { count, double, inc }
  }
}

过滤器迁移示例:

Vue2:

vue 复制代码
<span>{{ price | currency }}</span>

Vue3:

vue 复制代码
<script setup>
const currency = (n:number) => new Intl.NumberFormat('zh-CN', { style:'currency', currency:'CNY' }).format(n)
</script>
<span>{{ currency(price) }}</span>

Mixin → Composable:

Vue2 Mixin:

js 复制代码
export const userMixin = { created(){ this.fetchUser() }, methods:{ fetchUser(){ /*...*/ } } }

Vue3 Composable:

ts 复制代码
import { ref, onMounted } from 'vue'
export function useUser(){ const user = ref(null); onMounted(async()=>{ user.value = await fetchUser() }); return { user } }

工程化与生态替换

  • 构建:推荐 Vite,配合 unplugin-auto-import/unplugin-vue-components 按需引入
  • 路由:Vue Router v4 的组合式导航守卫与动态路由
  • 状态:Pinia 替代 Vuex,类型推断更友好,Action/Getter 更简化
  • DevTools:Vue3 Devtools 支持组件树、响应式追踪与性能面板

Vuex → Pinia 映射:

复制代码
state → state()
getters → getters
mutations/actions → actions(无需区分)
modules → 多 store + 组合式复用

性能与可维护性提升点

  • 编译时优化:静态节点提升、指令与属性打标,减少运行时比较开销
  • 事件缓存与 v-once/v-memo:降低重复绑定成本
  • 多根/Fragment:减少不必要的包裹元素,简化结构

编译优化说明:

  • 静态提升:模板中不变节点移出渲染函数缓存
  • Patch Flags:为动态节点打标(如 CLASS/PROPS/TEXT),运行时精准比对
  • 事件缓存:重复事件绑定存储与复用,降低创建成本

微基准建议:

  • 渲染 1k 列表对比 CSR(Vue2)与 Vue3 静态提升,记录渲染时长与内存占用

迁移检查清单

  • 全局 API 改为 app.xxx,插件通过 app.use
  • 移除 filters,替换为方法/计算
  • 统一插槽与事件:emits 显式声明事件,校验参数
  • v-model 改造为 modelValue/update:modelValue,必要时支持多 v-model:prop
  • 指令钩子更名与依赖修正(遇到 DOM 依赖逻辑用 onMounted
  • Mixins 清理与合并到组合式函数;抽象副作用为可停止的 Hooks

Router 迁移提示:

  • Vue Router v3 的导航守卫(beforeRouteEnter)迁移为 v4 组合式 onBeforeRouteUpdate 或全局守卫;动态路由改用 useRoute/useRouter

常见坑与修复

  • setup 访问 this(无实例):用返回对象或 getCurrentInstance
  • 深层响应式误用:基础类型用 ref,对象用 reactive;避免对 reactive 顶层整体替换
  • watch 触发过多:监听具体 getter 或 toRef;需要深度时再加 { deep: true }
  • v-model 不生效:对齐子组件 modelValueupdate:modelValue 协议

总结

  • Vue3 在性能、类型与工程化方面显著优于 Vue2,核心差异集中在响应式原理与生命周期映射
  • 迁移以增量方式进行:先兼容运行,逐项替换 API 与模式,再落地 Composition API 与生态升级
  • 借助工具链与编译优化,项目可得到更好的可维护性与长期演进空间

总览:为什么升级到 Vue3

  • 性能:编译时优化(静态提升、Patch Flags、缓存事件处理),初始化与更新更快
  • 体积与可维护:模块化与 Tree-Shaking,按需引入核心能力
  • 类型与工程:原生 TypeScript 支持、Composition API 提升代码组织与复用
  • 能力扩展:Teleport、Suspense、Fragments、Multi-root、异步组件更友好

响应式原理差异

  • Vue2:Object.defineProperty 拦截对象属性读取/设置,数组通过原型方法劫持;无法直接监听新增/删除属性,需 Vue.set/ Vue.delete
  • Vue3:Proxy 拦截对象/数组/Map/Set 等结构,配合 track/trigger 精细依赖收集与更新
js 复制代码
// Vue2 思路(简化):
function defineReactive(obj, key) {
  let val = obj[key]
  Object.defineProperty(obj, key, {
    get() { /* 依赖收集 */ return val },
    set(nv) { if (nv !== val) { val = nv; /* 派发更新 */ } }
  })
}

// Vue3 思路(简化):
const reactive = (target) => new Proxy(target, {
  get(t, k, r) { /* track(t,k) */ return Reflect.get(t, k, r) },
  set(t, k, v, r) { const ok = Reflect.set(t, k, v, r); /* trigger(t,k) */ return ok }
})
  • Vue3 响应式 API:reactive(对象代理)、ref(值容器)、computed(派生)、watch/watchEffect(副作用)、shallowRef/shallowReactivemarkRaw/toRaw
  • 变更点:
    • 不再需要 Vue.set,可直接新增属性并触发更新
    • ref 在模板自动解包,脚本需 .value
    • Map/Set 等原生结构可响应

细节对比:

  • 依赖收集精度:Vue3 基于 effect 栈与 targetMap,按 key 维度收集;Vue2 以对象级别收集,数组依赖粗粒度
  • 性能:Vue3 静态提升与 Patch Flags 减少遍历与 diff;Vue2 运行时比对更重
  • 数据结构:Vue3 支持 WeakMap/Map/Set 代理;Vue2 仅对象/数组可观测

生命周期映射与差异

  • Vue2 Options:beforeCreate/created/mounted/updated/destroyed
  • Vue3 Composition:以 setup 为入口,onMounted/onUpdated/onUnmounted 等组合式钩子
txt 复制代码
Vue2 → Vue3 对照:
- beforeCreate/created → setup(初始化)
- beforeMount/mounted → onBeforeMount/onMounted
- beforeUpdate/updated → onBeforeUpdate/onUpdated
- beforeDestroy/destroyed → onBeforeUnmount/onUnmounted
- activated/deactivated → onActivated/onDeactivated(KeepAlive)
  • 渲染入口:Vue2 使用 new Vue({ el, render }),Vue3 使用 createApp(App).mount('#app')
  • 模板:Vue3 支持多根节点与 Fragment;$listeners/$scopedSlots 合并为统一 slotsemits

指令钩子映射:

复制代码
bind → beforeMount
inserted → mounted
update → updated
componentUpdated → updated(或结合 onUpdated)
unbind → unmounted

语法与 API 差异(高频)

  • v-model:
    • Vue2:v-model 语法糖=value+input
    • Vue3:默认 modelValue + update:modelValue,支持多 v-model:prop
  • 过滤器(filters):移除,改为计算属性/方法
  • 全局 API:
    • Vue2:Vue.use/ Vue.mixin/ Vue.component
    • Vue3:实例化后通过 app.use/ app.mixin/ app.component
  • 插槽:作用域插槽统一为 slots,无需 slot-scope
  • 自定义指令:钩子更名(bindbeforeMountinsertedmounted

多模型 v-model 示例:

vue 复制代码
<Child v-model:visible="show" v-model:title="title" />
ts 复制代码
// 子组件
const props = defineProps<{ visible: boolean; title: string }>()
const emit = defineEmits<{ (e:'update:visible', v:boolean):void; (e:'update:title', v:string):void }>()

迁移方案(增量落地)

  • 依赖与兼容:
    • 使用 @vue/compat(迁移构建)在 Vue3 上运行 Vue2 代码,观察兼容警告并逐项修复
    • 升级生态:Vue Router v4、Pinia(或保留 Vuex 4)、Vite 构建
  • 组件改造路径:
    • filters → 函数/计算属性
    • v-modelmodelValue/update:modelValue(必要时支持多模型)
    • $listeners/$scopedSlotsemits/slots
    • mixins → 组合式函数(Composables),避免隐式依赖与命名冲突
  • 响应式修正:
    • 取消 Vue.set/delete,直接修改对象属性即可响应
    • 对深数据结构采用 reactive,基础类型用 ref
  • 生命周期重映射:将 created 初始化逻辑迁入 setup;副作用统一收敛到 onMounted/onUnmountedwatch

兼容构建使用:

js 复制代码
// vue.config.js 或构建配置中启用 @vue/compat
module.exports = { configureWebpack: { resolve: { alias: { 'vue': '@vue/compat' } } } }

在运行时观察兼容警告,逐项替换到 Vue3 API。

示例:Options API → Composition API

Vue2:

js 复制代码
export default {
  data() { return { count: 0 } },
  computed: { double() { return this.count * 2 } },
  created() { this.init() },
  methods: { init() {}, inc() { this.count++ } }
}

Vue3:

ts 复制代码
import { ref, computed, onMounted } from 'vue'
export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)
    const inc = () => { count.value++ }
    onMounted(() => init())
    function init() {}
    return { count, double, inc }
  }
}

过滤器迁移示例:

Vue2:

vue 复制代码
<span>{{ price | currency }}</span>

Vue3:

vue 复制代码
<script setup>
const currency = (n:number) => new Intl.NumberFormat('zh-CN', { style:'currency', currency:'CNY' }).format(n)
</script>
<span>{{ currency(price) }}</span>

Mixin → Composable:

Vue2 Mixin:

js 复制代码
export const userMixin = { created(){ this.fetchUser() }, methods:{ fetchUser(){ /*...*/ } } }

Vue3 Composable:

ts 复制代码
import { ref, onMounted } from 'vue'
export function useUser(){ const user = ref(null); onMounted(async()=>{ user.value = await fetchUser() }); return { user } }

工程化与生态替换

  • 构建:推荐 Vite,配合 unplugin-auto-import/unplugin-vue-components 按需引入
  • 路由:Vue Router v4 的组合式导航守卫与动态路由
  • 状态:Pinia 替代 Vuex,类型推断更友好,Action/Getter 更简化
  • DevTools:Vue3 Devtools 支持组件树、响应式追踪与性能面板

Vuex → Pinia 映射:

复制代码
state → state()
getters → getters
mutations/actions → actions(无需区分)
modules → 多 store + 组合式复用

性能与可维护性提升点

  • 编译时优化:静态节点提升、指令与属性打标,减少运行时比较开销
  • 事件缓存与 v-once/v-memo:降低重复绑定成本
  • 多根/Fragment:减少不必要的包裹元素,简化结构

编译优化说明:

  • 静态提升:模板中不变节点移出渲染函数缓存
  • Patch Flags:为动态节点打标(如 CLASS/PROPS/TEXT),运行时精准比对
  • 事件缓存:重复事件绑定存储与复用,降低创建成本

微基准建议:

  • 渲染 1k 列表对比 CSR(Vue2)与 Vue3 静态提升,记录渲染时长与内存占用

迁移检查清单

  • 全局 API 改为 app.xxx,插件通过 app.use
  • 移除 filters,替换为方法/计算
  • 统一插槽与事件:emits 显式声明事件,校验参数
  • v-model 改造为 modelValue/update:modelValue,必要时支持多 v-model:prop
  • 指令钩子更名与依赖修正(遇到 DOM 依赖逻辑用 onMounted
  • Mixins 清理与合并到组合式函数;抽象副作用为可停止的 Hooks

Router 迁移提示:

  • Vue Router v3 的导航守卫(beforeRouteEnter)迁移为 v4 组合式 onBeforeRouteUpdate 或全局守卫;动态路由改用 useRoute/useRouter

常见坑与修复

  • setup 访问 this(无实例):用返回对象或 getCurrentInstance
  • 深层响应式误用:基础类型用 ref,对象用 reactive;避免对 reactive 顶层整体替换
  • watch 触发过多:监听具体 getter 或 toRef;需要深度时再加 { deep: true }
  • v-model 不生效:对齐子组件 modelValueupdate:modelValue 协议

总结

  • Vue3 在性能、类型与工程化方面显著优于 Vue2,核心差异集中在响应式原理与生命周期映射
  • 迁移以增量方式进行:先兼容运行,逐项替换 API 与模式,再落地 Composition API 与生态升级
  • 借助工具链与编译优化,项目可得到更好的可维护性与长期演进空间
相关推荐
To_OC7 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC7 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic7 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy7 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志8 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble9 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长9 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯10 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜10 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司11 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能