Vue2与Vue3: 关键差异与新特性介绍

发布于:2024-10-08 ⋅ 阅读:(6) ⋅ 点赞:(0)

目录

一、Vue 2 与 Vue 3 的关键差异

1.双向数据绑定原理:

Object.defineProperty() 的作用

Proxy API 简介

2.支持碎片(Fragment)

为什么支持碎片很重要?

如何实现的?

3.API类型

4.数据变量和方法的定义

5.生命周期钩子

Vue 2 生命周期钩子

Vue 3 生命周期钩子

两者之间主要的区别:

1. 引入方式

2. 使用场合

3. 响应式函数

4. 组合性

5. 生命周期顺序

6. 与模板的关系

6.父子传参

Vue 2 的父子传参

Vue 3 的父子传参

主要区别

7. 指令与插槽

8. main.js 文件的不同

二、Vue 3 的新特性

1. Fragments、Teleport 和 createRenderer

2. Composition API

3. 更好的 TypeScript 支持

4. 性能提升

5. 更易维护

三、非兼容变更

四、移除的 API

五、总结


一、Vue 2 与 Vue 3 的关键差异

1.双向数据绑定原理:

  • Vue2:

使用Object.defineProperty() 对属性进行劫持,结合发布订阅模式实现数据响应

仅仅能监听属性,不支持对整个对象的监听,且不适用于数组

Object.defineProperty() 的作用

Object.defineProperty() 方法允许精确地添加或修改对象的属性。此方法接收三个参数:

  1. 要添加属性的对象。
  2. 属性的名称。
  3. 一个描述符对象,该对象指定了属性的值、可写性、可枚举性、可配置性等。

例如:

let data = { val: 0 };
Object.defineProperty(data, 'prop', {
  get: function() {
    return this.val;
  },
  set: function(newVal) {
    this.val = newVal;
  },
  enumerable: true,
  configurable: true
});

这个例子定义了一个名为 prop 的属性,它读取和设置内部 val 属性的值。

  • Vue3:

采用ES6 Proxy API 对数据进行代理,实现更高效的数据监听

支持对对象和数组的监听,能够更细致地捕捉数据变化

Proxy API 简介

Proxy 是 ES6 引入的一种新的数据结构,它允许你创建一个对象的代理,从而在访问对象的属性或方法时进行拦截和自定义操作。Proxy 对象有两个参数:目标对象和处理器对象,处理器对象定义了当操作被执行时的自定义行为。

let target = { message: 'Hello' };
let handler = {
    get(target, property, receiver) {
        console.log(`Property ${property} has been read.`);
        return Reflect.get(target, property, receiver);
    },
    set(target, property, value, receiver) {
        console.log(`Property ${property} set to ${value}.`);
        return Reflect.set(target, property, value, receiver);
    }
};

let proxy = new Proxy(target, handler);
proxy.message; // Property message has been read.
proxy.message = 'Hi'; // Property message set to Hi.

2.支持碎片(Fragment)

  • Vue2:不支持多个根节点
  • Vue3:支持多个根节点,增加了组件的灵活性

为什么支持碎片很重要?

更自然的模板结构:开发者可以更自然地编写模板,而不必为了满足单一根节点的限制而进行额外的包装。

避免不必要的 DOM 操作:不需要额外的包装元素,减少了 DOM 操作和潜在的性能影响。

更好的组件封装:组件可以返回多个独立的 DOM 元素,使得组件的封装和复用更加灵活。

提高代码的可维护性:模板结构更清晰,有助于提高代码的可读性和可维护性。

如何实现的?

Vue 3 使用了 Fragment 指令来实现对多个根节点的支持。在编译阶段,Vue 3 会将多个根节点的模板编译为一个 Fragment 节点,然后在渲染过程中,将 Fragment 节点拆分为多个独立的 DOM 元素。

3.API类型

  • Vue2:采用选项式API,将逻辑分割成data、computed、methods等部分
  • Vue3:采用组合式API,提供更灵活的逻辑组织方式

4.数据变量和方法的定义

Vue2:数据通过data()函数定义,方法在 methods 对象中定义

Vue3:引入setup()函数作为组件的入口点,集中定义数据和方法

5.生命周期钩子

Vue 2 生命周期钩子

Vue 2 的生命周期钩子分为几个阶段:

  1. 创建阶段

    • beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
    • created:在实例创建完成后被调用,此时,实例已完成数据观测、属性和方法的运算,$el 属性还未显示出来。
  2. 挂载阶段

    • beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。
    • mounted:在 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子,此时可以访问到 DOM 元素。
  3. 更新阶段

    • beforeUpdate:在数据变化之后,DOM 重新渲染之前调用,此时可以在这个钩子中进一步地更改状态。
    • updated:在由于数据更改导致的虚拟 DOM 重新渲染和打补丁后调用。
  4. 销毁阶段

    • beforeDestroy:在实例销毁之前调用,进行一些清理工作。
    • destroyed:在实例销毁后调用。

Vue 3 生命周期钩子

Vue 3 引入了 Composition API,带来了一组新的生命周期钩子,这些钩子在 setup 函数中使用:

  1. 创建阶段

    • setup:是 Composition API 的入口点,在组件实例创建之前执行,可以在这里声明响应式数据和函数。
  2. 挂载阶段

    • onBeforeMount:在挂载开始之前被调用,与 Vue 2 的 beforeMount 钩子相对应。
    • onMounted:在组件第一次挂载到 DOM 后调用,与 Vue 2 的 mounted 钩子相对应。
  3. 更新阶段

    • onBeforeUpdate:在更新开始之前被调用,与 Vue 2 的 beforeUpdate 钩子相对应。
    • onUpdated:在组件更新 DOM 后调用,与 Vue 2 的 updated 钩子相对应。
  4. 销毁阶段

    • onBeforeUnmount:在组件销毁之前调用,与 Vue 2 的 beforeDestroy 钩子相对应。
    • onUnmounted:在组件销毁后调用,与 Vue 2 的 destroyed 钩子相对应。

两者之间主要的区别:

1. 引入方式
  • Vue 2

    • 生命周期钩子是组件选项对象的一部分,不需要从外部引入。
  • Vue 3

    • 生命周期钩子函数需要从 vue 包中显式引入。
    • 使用组合式 API 时,这些生命周期钩子作为函数导入并在 setup 函数内部使用。
2. 使用场合
  • Vue 2

    • 生命周期钩子作为组件选项对象的属性来定义,例如 created()mounted(), 等等。
  • Vue 3

    • 在 setup 函数内部使用生命周期钩子,这是 Composition API 的一部分。

3. 响应式函数

  • Vue 2

    • 在 created 或 beforeMount 钩子中定义的响应式数据和函数可以直接通过 this 访问。
  • Vue 3

    • 在 setup 函数中定义的响应式数据和函数需要从 setup 返回,以便在模板或其他 Composition API 钩子中使用。

4. 组合性

  • Vue 2

    • 选项式 API 中的生命周期钩子是分离的,每个钩子处理不同的逻辑。
  • Vue 3

    • 使用组合式 API 时,生命周期钩子可以与响应式状态、计算属性和其他函数一起组合在 setup 函数中。

5. 生命周期顺序

  • Vue 2 和 Vue 3
    • 生命周期的顺序和阶段在两者中保持一致,但是 Vue 3 引入了新的 setup 阶段,这是在 beforeCreate 之前执行的。

6. 与模板的关系

  • Vue 2

    • 生命周期钩子中定义的响应式数据和函数自动与模板关联。
  • Vue 3

    • 在 setup 函数中返回的响应式数据和函数被模板使用。

6.父子传参

Vue 2 的父子传参

在 Vue 2 中,父子组件之间的参数传递主要依靠 props 和事件:

父传子(Props)

  • 父组件通过 props 向子组件传递数据。
  • 子组件通过声明 props 来接收来自父组件的数据。
// 子组件
export default {
  props: ['message']
};

子传父(事件)

  • 子组件使用 this.$emit 方法触发事件,并将数据传递给父组件。
  • 父组件在子组件标签上监听这些事件
// 子组件
this.$emit('my-event', someData);

// 父组件
<ChildComponent @my-event="handleEvent"/>

Vue 3 的父子传参

Vue 3 保留了 Vue 2 的 props 和事件机制,但在组合式 API(setup 函数)中引入了 emit 函数,提供了一种新的方式来处理子组件向父组件传递数据:

  • 父传子(Props)

    与 Vue 2 类似,父组件通过 props 向子组件传递数据。
  • 子传父(事件)

    在 Vue 3 的 setup 函数中,emit 函数作为参数传入,可以直接使用,而不需要通过 this.$emit
// 子组件
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup(props, { emit }) {
    // 直接使用 emit 触发事件
    function sendMessage() {
      emit('my-event', 'Hello from child');
    }

    return { sendMessage };
  }
});
  • 父组件的事件监听方式不变,仍然使用 @event 语法。
// 父组件
<ChildComponent @my-event="handleEvent"/>

主要区别

  • 子传父(组合式 API 中的 emit 函数)
    • Vue 3 中的 setup 函数为子组件提供了一个新的 emit 函数,使得事件触发更加直观和方便。
    • 这种新的事件触发方式仅在组合式 API 中使用,选项式 API 中的事件触发方式与 Vue 2 相同。

7. 指令与插槽

  • Vue 2slot 指令直接使用,v-for 优先级高于 v-if
  • Vue 3slot 指令需要使用 v-slot 的形式,v-for 和 v-if 可以更自然地结合使用。

8. main.js 文件的不同

  • Vue 2:使用构造函数的形式创建 Vue 应用。
  • Vue 3:使用工厂函数的形式,允许更灵活的应用创建方式。

二、Vue 3 的新特性

1. Fragments、Teleport 和 createRenderer

  • Fragments:允许组件拥有多个根节点,增加了组件的灵活性。
  • Teleport:能够将组件的某些部分传送到 DOM 中的其他位置,解决了 modals、toast 等元素的定位问题。
  • createRenderer:提供了创建自定义渲染器的能力,可以将 Vue 的开发模型扩展到其他平台。

2. Composition API

Composition API 提供了一种更灵活、更易于维护的方式来组织组件逻辑,支持逻辑的复用。它包括 refreactivecomputedwatch 等响应式函数,以及 setup() 函数作为组件的入口点。

3. 更好的 TypeScript 支持

Vue 3 重写时考虑了 TypeScript 的支持,使得开发者能够享受到更好的类型推断和类型检查。

4. 性能提升

Vue 3 在虚拟 DOM 的重写、组件初始化和编译模板方面进行了优化,提高了性能。Vue 3 的响应式系统和组件初始化过程也得到了改进,使得组件更新更快。

5. 更易维护

Vue 3 的架构改进使得代码更易于维护,同时提供了更好的逻辑组合和复用。

三、非兼容变更

Vue 3 带来了一些非兼容的变更,如全局 API 的更改、模板指令的变化、组件定义方式的调整等。这些变更虽然可能需要开发者对现有代码进行调整,但它们旨在提供更好的性能和更灵活的用法。

四、移除的 API

Vue 3 移除了一些 Vue 2 的 API,如 keyCode 修饰符、$on$off$once 实例方法、过滤器(filter)等。对于这些移除的 API,Vue 3 提供了替代方案,以帮助开发者平滑迁移。

五、总结

Vue 3 带来了许多令人兴奋的新特性和改进,包括组合式 API、更好的 TypeScript 支持、性能提升等。同时,它也进行了一些非兼容的变更和移除了一些 API。对于 Vue 开发者来说,Vue 3 提供了更多的可能性和更好的开发体验。


网站公告

今日签到

点亮在社区的每一天
去签到