Vue 3.0 核心特性技术日志

作为从 Vue 1.0 一路使用过来的开发者,Vue 3.0 并非简单的版本迭代,而是在核心架构、性能、开发体验上的全面升级,同时兼容了 2.x 的大部分核心思想,既保留了我们熟悉的开发范式,又解决了 2.x 长期存在的痛点。以下从核心架构、语法特性、性能优化、工程化等维度,结合 2.x 对比梳理关键变化。

一、核心架构:从 Options API 到 Composition API

1. Vue 2.x:Options API 为主

Vue 2.x 采用「选项式 API」,将代码按 datamethodscomputedwatch生命周期钩子 等选项划分,优点是上手简单,但存在明显痛点:

  • 逻辑碎片化:一个业务逻辑(如「用户登录状态管理」)的代码会分散在 data(状态)、methods(方法)、watch(监听)、mounted(初始化)等多个选项中,组件越大,逻辑越难追踪;
  • 代码复用受限:mixins 是主要复用方式,但存在命名冲突、来源不清晰、逻辑依赖隐晦的问题;
  • TypeScript 支持薄弱:Options API 天生不契合 TS 的类型推导,需要额外的类型声明,开发体验差。

2. Vue 3.0:Composition API(组合式 API)+ 保留 Options API

Vue 3.0 推出「组合式 API」,核心是 setup 函数(组件的入口),允许按业务逻辑维度组织代码,而非按选项类型:


<template>

<div>{{ count }}</div>
  <button @click="increment">+1</button>
</template>

<script setup>
// Vue 3.0 组合式 API(<script setup> 语法糖)
import { ref, computed, onMounted } from 'vue'

// 状态定义(替代 2.x 的 data)
const count = ref(0)

// 方法定义(替代 2.x 的 methods)
const increment = () => {
  count.value++
}

// 计算属性(替代 2.x 的 computed)
const doubleCount = computed(() => count.value * 2)

// 生命周期(替代 2.x 的 mounted)
onMounted(() => {
  console.log('组件挂载完成,count 初始值:', count.value)
})
</script>

核心优势

  • 逻辑聚合:一个业务逻辑的所有代码(状态、方法、监听、生命周期)可集中写在一处,组件结构更清晰;
  • 灵活复用:通过「组合函数(Composables)」复用逻辑(如 useUser()useRequest()),替代 mixins,解决命名冲突和依赖问题;
  • 完美支持 TS:基于函数式的写法天然契合 TS 类型推导,无需额外声明即可获得完整的类型提示。

兼容说明:Vue 3.0 完全保留 Options API,2.x 的代码可直接迁移(仅需少量适配),支持「渐进式升级」—— 既可以在老组件中继续用 Options API,也可以在新组件中用 Composition API。

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

1. Vue 2.x:响应式的痛点

Vue 2.x 基于 Object.defineProperty 实现响应式,存在天然限制:

  • 无法监听数组下标修改(如 arr[0] = 1)和数组长度修改(如 arr.length = 0),需通过 Vue.set/this.$set 或数组变异方法(push/splice)触发更新;
  • 无法监听对象新增属性/删除属性(如 this.obj.newKey = 1),同样需要 Vue.set/this.$delete
  • 响应式初始化时需要递归遍历对象,性能随对象层级加深下降。

2. Vue 3.0:Proxy 重构响应式

Vue 3.0 改用 ES6 的 Proxy 实现响应式,彻底解决上述问题:

  • 原生支持监听数组下标/长度修改、对象新增/删除属性,无需 $set/$delete
  • 非侵入式:无需修改原对象,而是代理对象,初始化时无需递归遍历(懒代理,访问属性时才递归),性能大幅提升;
  • 支持 RefReactive 两种响应式方式:
    • ref:用于基础类型(字符串、数字等),通过 .value 访问(模板中自动解包,无需 .value);
    • reactive:用于对象/数组,返回代理对象,直接访问属性即可。

示例对比

// Vue 2.x
export default {
  data() {
    return {
      arr: [1, 2, 3],
      obj: { name: 'Vue2' }
    }
  },
  methods: {
    updateData() {
      // 无效:无法监听数组下标修改
      this.arr[0] = 100
      // 有效:需用 $set
      this.$set(this.arr, 0, 100)

      // 无效:无法监听对象新增属性
      this.obj.age = 3
      // 有效:需用 $set
      this.$set(this.obj, 'age', 3)
    }
  }
}

// Vue 3.0(Composition API)
import { ref, reactive } from 'vue'
const arr = ref([1, 2, 3])
const obj = reactive({ name: 'Vue3' })

const updateData = () => {
  // 有效:原生支持数组下标修改
  arr.value[0] = 100
  // 有效:原生支持对象新增属性
  obj.age = 3
}

三、性能优化:体积、渲染、编译全方位提升

1. 体积更小

  • Vue 2.x 运行时体积约 22KB(gzip);
  • Vue 3.0 通过「树形摇树(Tree-shaking)」重构核心代码,仅引入使用的功能(如仅用响应式、不用编译器),最小体积约 10KB(gzip),体积减少 50% 以上。

2. 渲染更快

  • 虚拟 DOM 重构:Vue 3.0 优化了虚拟 DOM 的生成和对比算法,引入「静态标记」—— 对模板中不变的节点(如纯文本、静态标签)做标记,对比时直接跳过,渲染性能提升约 55%;
  • 编译优化:Vue 3.0 的模板编译器会提前分析模板结构,生成更高效的渲染函数,更新性能提升约 133%。

3. 内存占用更低

Vue 3.0 优化了组件实例的内存占用,同场景下内存使用减少约 50%。

四、其他关键变化(对比 Vue 2.x)

1. 生命周期钩子

Vue 3.0 保留了 2.x 的生命周期概念,但命名略有调整(Composition API 中),且新增 setup 替代 beforeCreatecreated Vue 2.x Vue 3.0(Composition API) 说明
beforeCreate setup(开始) setup 执行时,组件实例未创建
created setup(结束) setup 执行完,组件实例已创建
beforeMount onBeforeMount 挂载前
mounted onMounted 挂载后
beforeUpdate onBeforeUpdate 更新前
updated onUpdated 更新后
beforeDestroy onBeforeUnmount 卸载前(命名更语义化)
destroyed onUnmounted 卸载后(命名更语义化)

2. 模板语法

  • 支持多根节点:Vue 2.x 模板要求唯一根节点,3.0 支持多根节点(Fragment),无需包裹 `
    `;
  • 更灵活的 v-model:Vue 2.x 中 v-model 本质是 value + input 事件,3.0 支持自定义绑定属性和事件,且支持多个 v-model:

    <!-- Vue 2.x:仅能绑定一个 v-model,且固定 value/input -->
    <Child v-model="name" />
    
    <!-- Vue 3.0:支持多个 v-model,自定义属性和事件 -->
    <Child v-model:name="name" v-model:age="age" />
  • 移除 filter:Vue 3.0 废弃了 2.x 的 filter 过滤器,推荐用计算属性或方法替代(减少 API 复杂度)。

3. 全局 API 调整

Vue 2.x 的全局 API(如 Vue.componentVue.directive)会污染全局环境,3.0 改为「实例化 API」:

// Vue 2.x
import Vue from 'vue'
Vue.component('MyComponent', { /* ... */ })
Vue.directive('my-dir', { /* ... */ })
new Vue({ el: '#app' })

// Vue 3.0
import { createApp } from 'vue'
const app = createApp({ /* 根组件 */ })
app.component('MyComponent', { /* ... */ })
app.directive('my-dir', { /* ... */ })
app.mount('#app')

优势:多个 Vue 实例可独立配置,避免全局配置冲突(如多应用嵌入场景)。

4. 废弃/不推荐的特性

  • 废弃 Vue.prototype:改用 app.config.globalProperties 挂载全局属性;
  • 废弃 $on/$off/$once:移除实例事件总线,推荐用第三方库(如 mitt)替代;
  • 不推荐 filters:用计算属性/方法替代;
  • 不推荐 mixins:用 Composition API 的组合函数替代。

五、迁移建议(从 Vue 2.x 到 3.0)

  1. 渐进式迁移:先保留 Options API,逐步在新功能中使用 Composition API,降低迁移成本;
  2. 工具适配:升级脚手架到 Vite(Vue 3.0 推荐)或 Vue CLI 5+,安装 @vue/compat 兼容包,可临时兼容 2.x 代码;
  3. 重点检查
    • 替换 Vue.set/$setVue.delete/$delete(3.0 无需);
    • 调整生命周期钩子(如 beforeDestroyonBeforeUnmount);
    • 替换 filter 为计算属性/方法;
  4. TypeScript 接入:新组件建议用 <script setup lang="ts">,充分利用 3.0 的 TS 优势。

总结

  1. 核心架构:Vue 3.0 的 Composition API 解决了 2.x Options API 逻辑碎片化、复用难、TS 支持差的问题,同时兼容 2.x 写法,支持渐进式升级;
  2. 响应式系统:基于 Proxy 重构,彻底解决 2.x Object.defineProperty 无法监听数组/对象新增属性的痛点,性能和易用性大幅提升;
  3. 性能与体验:体积更小、渲染更快,模板语法更灵活(多根节点、多 v-model),全局 API 更合理,是对 Vue 2.x 核心痛点的全面优化,同时保留了 Vue 一贯的「易用、渐进式」设计理念。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注