从响应式原理到 Composition API

摘要:Vue3 并不是简单的版本迭代,而是底层架构的全面重构。本文从响应式原理、API 设计、性能优化、新特性、生命周期、生态工具六大维度,系统对比 Vue2 与 Vue3 的差异,并附代码示例,助你快速掌握 Vue3 革新之处。

对比维度

Vue2

Vue3

源码语言

JavaScript (Flow)

TypeScript 重写

核心 API

Options API(选项式)

Composition API(组合式)+ 兼容 Options API

响应式原理

Object.defineProperty

ES6 Proxy

打包体积

~23KB gzipped,无 Tree-Shaking

支持 Tree-Shaking,~13KB gzipped

多根节点

❌ 不支持(需包一层 div)

✅ 支持 Fragment

TypeScript

需第三方装饰器,类型推导弱

原生一等公民支持

状态管理

Vuex

Pinia(官方推荐)

构建工具

Vue CLI (Webpack)

Vite(推荐)

二、响应式系统:Object.defineProperty vs Proxy

Vue2 — Object.defineProperty

// Vue2 响应式简化原理
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      /* 依赖收集 */
      return val
    },
    set(newVal) {
      /* 通知更新 */
      val = newVal
    }
  })
}

局限

  • 无法监听对象新增/删除属性(需用 Vue.set/ Vue.delete

  • 数组索引/length 变化需 hack(splice等)

  • 初始化时需递归遍历所有属性,深层对象有性能开销

Vue3 — Proxy

import { reactive } from 'vue'

const state = reactive({ count: 0, info: { name: 'Vue3' } })
state.newProp = 100  // ✅ 直接响应,无需 Vue.set

优势

  • 监听整个对象,支持新增/删除属性、数组索引变化

  • 支持 MapSetWeakMap等集合类型

  • 惰性代理(访问时才递归),初始化性能更优


三、API 风格:Options API vs Composition API

Vue2 — Options API(按选项拆分)

// Vue2
export default {
  data() { return { count: 0 } },
  computed: { double() { return this.count * 2 } },
  methods: { inc() { this.count++ } },
  mounted() { console.log('mounted') }
}

❌ 同一业务逻辑的 data/methods/watch/生命周期被拆散,复杂组件难维护

Vue3 — Composition API(按逻辑聚合)

<!-- Vue3 <script setup> 语法(推荐) -->
<script setup>
import { ref, computed, onMounted } from 'vue'

const count = ref(0)
const double = computed(() => count.value * 2)
const inc = () => count.value++

onMounted(() => console.log('mounted'))
</script>

<template>
  <button @click="inc">{{ count }} / {{ double }}</button>
</template>

同一功能相关代码聚合,支持自定义 Composable Hook 复用(替代 mixin,无命名冲突)

四、生命周期钩子变化

Vue3 在 Composition API 中用 onXxx形式引入:

Vue2 (Options)

Vue3 (Composition API)

beforeCreate / created

setup() 替代(在这两个钩子前执行)

beforeMount

onBeforeMount

mounted

onMounted

beforeUpdate

onBeforeUpdate

updated

onUpdated

beforeDestroy

onBeforeUnmount

destroyed

onUnmounted

activated / deactivated

onActivated / onDeactivated

五、性能与编译优化(Vue3 新特性)

  • 静态提升(Static Hoisting):编译时将静态节点提到渲染函数外,跳过重复创建与 Diff

  • PatchFlag(补丁标记):编译时为动态节点打标记,Diff 时只对比带标记的节点

  • 事件监听器缓存:避免每次渲染生成新函数导致不必要子组件更新

  • 更高效的 Diff 算法:基于最长递增子序列减少 DOM 移动次数

六、全局 API 与 v-model 变化

应用实例创建(避免全局配置污染):

// Vue2
import Vue from 'vue'
new Vue({ render: h => h(App) }).$mount('#app')

// Vue3
import { createApp } from 'vue'
createApp(App).mount('#app')

v-model

  • Vue2:value+ @input.sync修饰符

  • Vue3:默认 modelValue+ @update:modelValue,支持多个 v-model 绑定

<Child v-model:title="title" v-model:visible="show" />

移除filters(用 computed/method 代替)、$on/$off/$once(事件总线用 mitt 等库替代)

七、生态与选型建议

项目场景

建议

✅ 新项目 / 中大型应用

Vue3 + Vite + Pinia + TS

✅ 需 TS 类型安全、逻辑复用

Vue3 Composition API

⚠️ 老项目无重大迭代

维持 Vue2

⚠️ 依赖仅支持 Vue2 的第三方库

暂留 Vue2

更多推荐