组合式 API(Composition API)

 前端   大苹果   2024-09-16 21:52   11

Vue 3 引入的 Composition API 是一套全新的 API,它的设计初衷是解决 Vue 2 中 Options API 难以重用逻辑和模块化的问题。Composition API 更加灵活,便于代码的逻辑抽离、模块化、复用性强,并且在大型项目中更具优势。它基于函数的编程风格,可以让我们在同一个 setup() 函数内组织组件的各种逻辑。

1. Composition API 的核心概念

1.1 setup 函数

setup 是 Vue 3 组件中使用 Composition API 的入口。在组件实例创建之前执行,它是 Composition API 的核心。在 setup 中,可以定义响应式状态、生命周期钩子、计算属性等。

export default {
  setup() {
    // 组件逻辑写在这里
    return {}; // 返回值将暴露给模板
  }
}

1.2 refreactive

  • ref:创建一个可以跟踪单个基本类型数据的响应式对象。当你使用 ref 创建一个响应式数据时,Vue 会自动将其包装为对象形式,该对象包含 .value 属性来保存数据。
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0); // 创建响应式变量
    const increment = () => {
      count.value++; // 通过 .value 访问和修改
    };

    return { count, increment };
  }
}
  • reactive:创建一个响应式对象,适用于复杂的结构,如对象或数组。
import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      user: {
        name: 'Alice',
        age: 30
      }
    });

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

    return { state, increment };
  }
}

1.3 computed 计算属性

computed 用于定义计算属性,它的返回值会根据依赖的响应式数据自动更新。

import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const double = computed(() => count.value * 2);

    return { count, double };
  }
}

1.4 watchwatchEffect

  • watch:监听响应式数据的变化,并执行回调函数。常用于异步操作或副作用逻辑。
import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
  
    watch(count, (newValue, oldValue) => {
      console.log(`count changed from ${oldValue} to ${newValue}`);
    });

    return { count };
  }
}
  • watchEffect:立即执行传入的副作用函数,并自动追踪依赖的响应式数据。
import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const count = ref(0);
  
    watchEffect(() => {
      console.log(`count is now: ${count.value}`);
    });

    return { count };
  }
}

1.5 生命周期钩子

Composition API 提供的生命周期钩子类似于 Options API 中的生命周期钩子,但需要通过函数调用形式使用。

  • onMounted:组件挂载完成后触发
  • onUnmounted:组件销毁前触发
  • onUpdated:组件更新后触发
import { onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('Component has been mounted');
    });

    onUnmounted(() => {
      console.log('Component is about to be destroyed');
    });

    return {};
  }
}

1.6 provideinject

  • provide:向下传递数据,使得祖先组件能够将数据提供给后代组件。
  • inject:接收来自祖先组件通过 provide 提供的数据。
// Parent.vue
import { provide, ref } from 'vue';

export default {
  setup() {
    const message = ref('Hello from Parent');
    provide('message', message); // 提供数据

    return {};
  }
}

// Child.vue
import { inject } from 'vue';

export default {
  setup() {
    const message = inject('message'); // 注入数据

    return { message };
  }
}

2. 组合式 API 的实际应用

2.1 创建一个计数器组件

我们可以通过 Composition API 实现一个简单的计数器组件。

<template>
  <div>
    <p>计数值:{{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);
    const increment = () => count.value++;

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

2.2 响应式数据与计算属性

我们可以通过 computedref 实现一个双倍计数器,并展示 Vue 3 中的响应式机制。

<template>
  <div>
    <p>计数值:{{ count }}</p>
    <p>双倍计数值:{{ doubleCount }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

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

export default {
  setup() {
    const count = ref(0);
    const doubleCount = computed(() => count.value * 2);

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

    return { count, doubleCount, increment };
  }
}
</script>

2.3 watch 实现副作用逻辑

通过 watch,我们可以实现对响应式数据的精确监听。

<template>
  <div>
    <p>计数值:{{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

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

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

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

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

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

3. 组合式 API 的优势

  • 逻辑拆分和复用:在 Vue 2 中,逻辑往往是通过生命周期钩子、数据和方法进行组织的,导致同一逻辑分散在组件的不同位置。而 Vue 3 的 Composition API 可以将相关的逻辑组合在一起,更容易复用和模块化。
  • 代码更简洁:Composition API 允许通过函数方式组织代码,使得代码逻辑更加集中。
  • 灵活性高:它为大型项目提供了更好的逻辑复用性,并且可以无缝集成 TypeScript。

4. 总结

Vue 3 的 Composition API 为我们提供了一种更灵活的方式来组织和复用代码。通过 setup 函数,我们可以创建更简洁、更易维护的组件。核心的 refreactivecomputedwatch 等工具帮助我们轻松管理响应式状态,同时生命周期钩子也变得更易于理解和使用。

对于开发大型项目,Composition API 提供了更强的灵活性和可维护性,建议在学习 Vue 3 时优先掌握这一新特性。