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 与生态升级
  • 借助工具链与编译优化,项目可得到更好的可维护性与长期演进空间
相关推荐
zlpzlpzyd1 小时前
vue.js 3项目整合vue-router 4的问题
前端·javascript·vue.js
crary,记忆1 小时前
Angular.json中的commonChunk 的作用
前端·javascript·学习·angular.js
Highcharts.js1 小时前
Highcharts 仪表板 CSS 样式定制使用说明
前端·css·仪表板·highcharts·css 样式
好奇的候选人面向对象1 小时前
大屏ECharts适配完整方案
前端·javascript·echarts
伍华聪1 小时前
介绍一个医疗物质数目清点系统的实现过程
前端
逆风局?1 小时前
后端Web实战(部门管理)——日志技术
java·前端