vue2和vue3的区别

61 阅读3分钟

一、响应式原理:从 Object.defineProperty 到 Proxy

维度Vue2Vue3
实现方式Object.defineProperty 劫持 getter/setterProxy 直接代理对象(ES6 特性)
监听颗粒度只能监听属性,无法监听数组索引修改可监听数组索引和对象属性,支持 Map/Set 等新类型
初始化性能递归遍历对象属性,大型对象初始化慢仅在属性被访问时建立响应式,初始化更快
内存占用每个属性需绑定 getter/setter,内存开销大Proxy 代理更高效,内存占用减少

二、API 设计:从选项式到组合式

1. 组件写法对比

<!-- Vue2 选项式 API -->
<template>
  <div>{{ count }}</div>
</template>
<script>
export default {
  data() { return { count: 0 } },
  methods: { increment() { this.count++ } },
  mounted() { console.log('mounted') }
}
</script>

<!-- Vue3 组合式 API (setup) -->
<template>
  <div>{{ count }}</div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
  setup() {
    const count = ref(0);
    const increment = () => count.value++;
    onMounted(() => console.log('mounted'));
    return { count, increment };
  }
}
</script>

2. 组合式 API 优势

  • 逻辑复用:通过自定义 Hook 函数(如 useMousePosition)复用逻辑,替代 Vue2 的 mixin(避免命名冲突)。
  • 类型推导:TypeScript 支持更友好,自动推导变量类型。
  • 代码组织:相关逻辑(如生命周期、计算属性)可集中在 setup 中,避免选项式的碎片化。

三、生命周期与钩子函数

Vue2 钩子Vue3 对应钩子组合式 API 钩子
beforeCreate移除(setup 替代初始化逻辑)-
created移除(setup 替代初始化逻辑)-
beforeMountbeforeMountonBeforeMount
mountedmountedonMounted
beforeUpdatebeforeUpdateonBeforeUpdate
updatedupdatedonUpdated
beforeDestroybeforeUnmountonBeforeUnmount
destroyedunmountedonUnmounted
errorCapturederrorCapturedonErrorCaptured

四、性能优化:编译与渲染引擎升级

  1. 编译优化

    • Vue3 引入 模板编译时优化
      • 静态内容(如 <div>标题</div>)会被标记为 static,不再进行响应式处理。
      • 动态内容(如 {{ count }})会被编译为更高效的渲染函数。
  2. 渲染性能

    • Vue3 的 diff 算法升级:
      • 新增 patchFlag 标记节点类型,避免无变化节点的重复比对。
      • 静态节点会被缓存,多次渲染时直接复用,减少 DOM 操作。
  3. 打包体积

    • Vue3 支持 tree-shaking:仅打包实际使用的 API(如 refreactive),体积比 Vue2 减少约 40%。

五、新特性与语法糖

  1. Composition API

    • 允许在 setup 中组合使用响应式、生命周期等逻辑,替代 Vue2 的选项式组织方式。
  2. Teleport(传送门)

    • 允许组件模板渲染到 DOM 树的任意位置(如弹窗渲染到 body 下):
      <teleport to="body">
        <div class="modal">弹窗内容</div>
      </teleport>
      
  3. Suspense(异步组件加载)

    • 处理异步组件加载状态,可定义加载中与错误状态:
      <suspense>
        <template #default>
          <AsyncComponent />
        </template>
        <template #fallback>
          <div>加载中...</div>
        </template>
      </suspense>
      
  4. Emits 声明强化

    • Vue3 中 emits 可声明为数组或对象,支持参数类型校验:
      emits: {
        submit: (payload) => typeof payload === 'object'
      }
      

六、问题

1. 问:Vue3 为什么用 Proxy 替代 Object.defineProperty?

    • Proxy 支持监听数组索引和对象属性的新增/删除(如 arr[0] = 1delete obj.key)。
    • Proxy 是 ES6 原生 API,性能优于递归定义 getter/setter,且可直接代理 Map/Set 等新类型。
    • Vue2 中数组变异方法(如 push)需单独封装,而 Vue3 原生支持数组响应式。

2. 问:组合式 API 相比选项式有什么优势?

    • 逻辑复用:通过 Hook 函数复用代码,避免 mixin 的命名冲突。
    • 类型推导:TypeScript 支持更完善,变量类型自动推导。
    • 代码组织:相关逻辑(如数据、方法、生命周期)集中在 setup 中,避免选项式的碎片化。

3. 问:Vue3 如何优化大型应用的性能?

    • 编译时优化:静态内容标记为 static,减少响应式处理。
    • diff 算法升级patchFlag 标记节点类型,跳过无变化节点比对。
    • tree-shaking:仅打包使用的 API,减少体积。
    • 静态节点缓存:多次渲染时直接复用,减少 DOM 操作。