一、什么是组合式API

组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:

  • 响应式 API:例如 ref() 和 reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
  • 生命周期钩子:例如 onMounted() 和 onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
  • 依赖注入:例如 provide() 和 inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。

二、为什么要有组合式 API?

  • 更好的逻辑复用​:组合式 API 最基本的优势是它使我们能够通过组合函数来实现更加简洁高效的逻辑复用。在选项式 API 中我们主要的逻辑复用机制是 mixins,而组合式 API 解决了 mixins 的所有缺陷。
  • 更灵活的代码组织:许多用户喜欢选项式 API 的原因是它在默认情况下就能够让人写出有组织的代码:大部分代码都自然地被放进了对应的选项里。然而,选项式 API 在单个组件的逻辑复杂到一定程度时,会面临一些无法忽视的限制。这些限制主要体现在需要处理多个逻辑关注点的组件中,这是我们在许多 Vue 2 的实际案例中所观察到的。
  • 更好的类型推导​
  • 更小的生产包体积

三、setup

组合式函数只能在<script setup>或 setup() 钩子中被调用。在这些上下文中,它们也只能被同步调用。

<script setup>是唯一在调用 await 之后仍可调用组合式函数的地方。编译器会在异步操作之后自动为你恢复当前的组件实例。

3.1 作用

setup 函数在组件创建之前被调用,它可以接收两个参数:props 和 context。这个函数的主要作用是:

  • 初始化组件的状态和数据。
  • 定义组件的方法、计算属性等。
  • 处理响应式数据和副作用。

3.2 参数介绍

props:

  • 包含了父组件传递给子组件的属性。
  • 是响应式的,但不能直接被修改。

context:

  • 是一个包含了一些属性的对象,如 attrs、slots、emit。
  • attrs:包含了父组件传递给子组件的非 props 属性。
  • slots:用来访问组件的插槽内容。
  • emit:用于触发自定义事件。

3.3使用方法

定义响应式数据:

  • 使用 ref 或 reactive 来创建响应式数据。
  • ref 用于创建基本类型的响应式数据,返回一个包含 .value 属性的对象。
  • reactive 用于创建对象类型的响应式数据。
<script setup>
    import { ref, reactive } from 'vue';

    const count = ref(0);
    const person = reactive({ name: '张三', age: 20 });
</script>

定义方法:

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

   const count = ref(0);
   const person = reactive({ name: '张三', age: 20 });

   function increment() {
     count.value++;
   }
</script>

计算属性:

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

   const count = ref(0);
   const person = reactive({ name: '张三', age: 20 });

   function increment() {
     count.value++;
   }

   const doubleCount = computed(() => count.value * 2);
</script>

监听数据变化:

<script setup>
   import { ref, reactive, watch } from 'vue';

   const count = ref(0);
   const person = reactive({ name: '张三', age: 20 });

   function increment() {
     count.value++;
   }

   const doubleCount = computed(() => count.value * 2);

   watch(count, (newValue, oldValue) => {
     console.log(`count 从 ${oldValue} 变为 ${newValue}`);
   });
</script>

触发自定义事件

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

   const count = ref(0);
   const person = reactive({ name: '张三', age: 20 });

   function increment() {
     count.value++;
     // 触发自定义事件
     emit('incremented');
   }

   const doubleCount = computed(() => count.value * 2);
</script>

3.4 注意事项

setup 函数是在组件创建之前执行的,所以在 setup 函数中无法访问到组件的实例 this。

在 setup 函数中定义的变量和方法,需要通过 return 返回才能在模板中使用。

setup 函数只能是一个同步函数,不能是异步函数。如果需要在 setup 中执行异步操作,可以在函数内部使用异步函数,但不能直接将 setup 函数定义为异步函数。

总之,setup 函数为 Vue 3 组件提供了更强大的逻辑组织和复用能力,使得组件的开发更加灵活和高效。

3.5 <script setup>和setup()函数区别

3.5.1 语法形式
  • <script setup>是一种新的语法糖,直接在