Composition API

103 阅读5分钟

Composition API和Options API的区别

  • 组织方式: Options API 是基于组件选项的,而 Composition API 是基于函数的。
  • 逻辑复用: Composition API 更灵活,可以更容易地将逻辑划分为可重用的功能,并在不同组件之间共享。
  • 更清晰的逻辑组织: Composition API 可以更自然地组织相关逻辑,避免了在大型组件中滚动和查找不同选项的情况。
  • 生命周期函数: 在 Composition API 中,生命周期函数是通过函数形式直接调用的,而不是通过特定的选项。

例子

Options API 示例:

vueCopy code
<template>
  <div>
    <p>{{ countMessage }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment() {
      this.count++;
    },
  },
  computed: {
    countMessage() {
      return `Count is: ${this.count}`;
    },
  },
};
</script>

在这个例子中,data 用于存储状态,methods 用于存储方法,computed 用于派生状态。这是典型的 Options API 结构。

Composition API 示例:

vueCopy code
<template>
  <div>
    <p>{{ countMessage }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);

    const increment = () => {
      count.value++;
    };

    const countMessage = computed(() => `Count is: ${count.value}`);

    return {
      countMessage,
      increment,
    };
  },
};
</script>

在这个例子中,使用了 setup 函数,而不再需要 datamethodscomputed 等选项。逻辑被组织在 setup 函数中,通过 ref 创建响应式数据,并且使用 computed 创建派生状态。

setup

在 Vue 3 中,setup 函数是 Composition API 的入口点,它负责设置组件的初始状态并返回给模板需要使用的数据和方法。setup 函数的存在使得组件的逻辑可以更加灵活地组织和共享。

主要原因包括:

  1. 作用域:setup 函数内部,可以使用 refreactive 等函数创建响应式数据,并将它们暴露给模板。这样可以有效地控制数据的作用域,避免了在模板中直接使用组件实例的属性,提高了代码的可维护性。
  2. 生命周期钩子: setup 函数内可以使用生命周期钩子,如 onMountedonUpdatedonUnmounted 等。这样,可以更方便地管理组件的生命周期逻辑。
  3. 模板中的数据暴露: setup 函数的返回值是模板可直接访问的数据和方法。通过 setup,可以更加清晰地定义组件的接口,让模板代码更具可读性。
  4. 逻辑组织:setup 函数中,可以使用普通的 JavaScript 语法,更容易组织和重用逻辑。这种方式相对于 Vue 2.x 中的 Options API 更加灵活和直观。

虽然 setup 函数是 Composition API 的核心,但并不是唯一的使用方式。在 setup 内部,您可以选择返回一个对象,也可以直接返回数据和方法。这取决于您的需求和个人偏好。通过 setup 函数,Vue 3 提供了更多的灵活性,让开发者更容易管理组件的状态和逻辑。

ref和reactive

在Vue.js中,将数据包装成响应式数据的目的是使数据的变化能够被Vue追踪,从而在数据变化时自动更新相关的视图。 refreactive 都是 Vue 3 Composition API 中用于创建响应式数据的函数,但它们在用法和适用场景上有一些区别。

ref:

  • 用于创建一个包装基本类型值的响应式对象。
  • 通过 ref 创建的对象,访问和修改值需要使用 .value
  • 通常用于创建单一的响应式数据。
javascriptCopy code
import { ref } from 'vue';

const count = ref(0);

console.log(count.value); // 读取值
count.value++; // 修改值

reactive:

  • 用于创建一个包装普通对象的响应式代理。
  • 通过 reactive 创建的对象,可以直接访问和修改属性,无需使用 .value
  • 通常用于创建包含多个属性的响应式对象。
javascriptCopy code
import { reactive } from 'vue';

const person = reactive({
  name: 'John',
  age: 25,
});

console.log(person.name); // 读取属性
person.age++; // 修改属性

区别和适用场景:

  • 当只需要创建一个基本类型值的响应式数据时,使用 ref 更方便。
  • 当需要创建一个包含多个属性的对象时,使用 reactive 更适合,因为它可以直接处理对象的多个属性,而不需要为每个属性都使用 .value
  • ref 适用于简单的场景,而 reactive 更适用于包含复杂结构的响应式对象。

为什么不使用object.definepropoty或者是proxy

使用 refreactive 而不直接使用 Object.definePropertyProxy 主要是为了提供更加高级且易用的 API,并隐藏底层的实现细节。这样做有以下几个原因:

  1. 语法糖: refreactive 提供了更简洁的语法,使得代码更易读和编写。使用 ref 可以直接将基本类型的值包装成响应式对象,而 reactive 则可以将整个对象变成响应式,而不用直接操作底层的 Object.definePropertyProxy
  2. 适用性广泛: ref 适用于单一的响应式数据,而 reactive 适用于复杂对象的响应式化。这样的 API 设计更符合开发者的常见使用场景,使得代码更容易理解。
  3. Vue 2.x 兼容性: Vue.js 在设计 Vue 3.x 时考虑到了向后兼容,因此继续使用了 refreactive 这样的 API,以保持对 Vue 2.x 代码的较好兼容性。
  4. 性能优化: Vue 在实现响应式系统时做了很多性能优化,包括异步更新、缓存机制等,这些优化对于提升应用的性能和用户体验是很重要的。

虽然底层的实现依然依赖于 Object.definePropertyProxy,但通过提供更高级的 API 接口,Vue 让开发者能够更方便地使用响应式数据,而无需直接处理底层的复杂性。这样的设计使得 Vue 的响应式系统更易用、更灵活,同时保持了底层的性能优势。