本文从架构、性能、开发体验、特性与工程化多个维度对比 Vue 2 与 Vue 3,并突出 Vue 3 的显著优势与迁移建议。

概览

  • Vue 3 核心重写(Proxy 响应式 + 新编译器),显著提升性能与可维护性。
  • Composition API 与 <script setup> 提升逻辑组织、复用与类型体验。
  • 更好的 Tree-Shaking、TypeScript 支持与生态(Vite、Pinia、SSR)。

架构与性能

  • 响应式机制:
    • Vue 2 使用 Object.defineProperty,对属性级拦截,不可检测新增/删除属性与索引变更;需 Vue.set/$set 补救。
    • Vue 3 使用 Proxy,对对象级拦截,天然支持新增/删除属性、数组索引与 Map/Set 等数据结构。
  • 依赖追踪:
    • Vue 3 引入 effect 与更细粒度的依赖图,减少不必要的重渲染。
  • 编译优化:
    • 静态提升、事件缓存、patchFlag 精确更新;大幅提高首屏与更新性能。
  • 体积与 Tree-Shaking:
    • Vue 3 模块化设计;未使用的功能在打包中可移除,减小 bundle。
  • TS 支持:
    • Vue 3 以 TS 编写,类型更完整;API 自带类型提示与推断。
// Vue 2 的响应式(简化示意)
const obj = { a: 1 }
// 新增属性需要 $set 才能响应
Vue.set(obj, 'b', 2)

// Vue 3 的响应式
import { reactive } from 'vue'
const state = reactive({ a: 1 })
state.b = 2 // 直接可响应

开发体验

  • Composition API:
    • 按逻辑分组而非选项分组,避免大型组件跨 data/methods/computed/watch 跳转。
    • 更易复用(抽取为可组合函数),更易测试与类型化。
  • <script setup>
    • 单文件组件更简洁,无需 export default;自动导出模板可用变量;编译期优化。
  • 更直观的生命周期与 watch:
    • onMounted/onUnmounted 等组合式钩子;watchEffectwatch 提供更灵活的副作用控制。
<!-- Vue 2:选项式 -->
<script>
export default {
  data() { return { count: 0 } },
  computed: { doubled() { return this.count * 2 } },
  methods: { inc() { this.count++ } }
}
</script>

<!-- Vue 3:组合式 -->
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
const inc = () => { count.value++ }
</script>

新特性与能力

  • 多根节点与 Fragment:
    • Vue 3 支持组件返回多个根节点,减少不必要的包裹元素。
  • Teleport:
    • 在不改变组件逻辑的情况下,将子树渲染到任意 DOM 容器(如全局模态层)。
  • Suspense:
    • 更优雅地处理异步组件加载与占位内容。
  • 新的 v-model 语义:
    • 支持多 v-model、自定义模型名;modelValueupdate:modelValue 事件约定。
  • Emits/Props 明确化:
    • emits 显式声明事件,提高可读性与类型安全。
<!-- Teleport 示例 -->
<template>
  <Teleport to="body">
    <div class="modal">Hello</div>
  </Teleport>
</template>

工程化与生态

  • 创建与挂载:
    • Vue 2:new Vue({ render }).$mount('#app')
    • Vue 3:createApp(App).use(router).mount('#app')
  • 插件与全局 API:
    • Vue 3 使用 app.use/app.component/app.directive,避免跨实例污染。
  • 状态管理:
    • 推荐使用 Pinia(更轻量、类型友好)替代 Vuex。
  • 构建工具:
    • 与 Vite 深度融合,快速冷启动、热更新与按需编译体验优异。
  • SSR 与服务端能力:
    • 新 SSR 渲染器、流式传输与更好并发支持。
// Vue 3 应用入口
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

迁移与兼容

  • 渐进迁移:
    • 可先将 Vue 2 升级到 2.7(支持部分 Composition API),再迁至 Vue 3。
  • 迁移构建:
    • 使用官方迁移构建捕捉弃用 API 与行为差异。
  • 常见差异:
    • 过滤器(filters)已移除;使用计算属性或方法替代。
    • v-on.native 移除,使用 emits 或在根元素绑定。
    • 插槽与作用域插槽语法统一;this 上下文在组合式中不再使用。

实战对比示例

异步加载与副作用

<!-- Vue 2:选项式 -->
<script>
export default {
  data() { return { user: null, loading: false, error: null } },
  methods: {
    async load() {
      this.loading = true
      try { this.user = await fetch('/api/user').then(r => r.json()) }
      catch (e) { this.error = e }
      finally { this.loading = false }
    }
  },
  created() { this.load() }
}
</script>
<!-- Vue 3:组合式 + 更清晰副作用控制 -->
<script setup>
import { ref, onMounted } from 'vue'
const user = ref(null)
const loading = ref(false)
const error = ref(null)

const load = async () => {
  loading.value = true
  try { user.value = await fetch('/api/user').then(r => r.json()) }
  catch (e) { error.value = e }
  finally { loading.value = false }
}

onMounted(load)
</script>

逻辑复用(组合函数)

// Vue 3:抽取为可复用的 useFetch 组合函数
import { ref } from 'vue'
export function useFetch(url) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref(null)
  const run = async () => {
    loading.value = true
    try { data.value = await fetch(url).then(r => r.json()) }
    catch (e) { error.value = e }
    finally { loading.value = false }
  }
  return { data, loading, error, run }
}

Vue 3 的关键优势总结

  • 更快:编译优化与更细粒度更新,减少不必要渲染。
  • 更小:模块化与 Tree-Shaking,减轻产物体积。
  • 更强:Proxy 响应式、Teleport/Suspense/Fragment 等新能力。
  • 更易维护:Composition API 与 <script setup> 改善组织与复用。
  • 更友好:一流的 TypeScript 支持与完善的 Devtools。
  • 更现代:与 Vite/Pinia/SSR 生态深度融合,开发与部署体验优异。

迁移建议

  • 优先在新增功能或重构模块中采用组合式写法与 <script setup>
  • 引入 Pinia 替代复杂的 Vuex 模块化方案,减少模板与样板代码。
  • 结合 Vite 进行构建,获得更快的开发与构建速度。
  • 使用官方迁移工具定位不兼容点,逐步替换弃用 API。

结论:在性能、可维护性与生态支持方面,Vue 3 全面优于 Vue 2,值得作为新项目与迁移目标的首选。