Vue3 组合式 API 提升代码可复用性和可维护性(十)

Vue3 的组合式 API(Composition API)是 Vue3 中引入的一项重要特性,旨在解决传统组件模式下代码复杂度高、可复用性差的问题。通过组合式 API,开发人员可以更灵活地组织和复用代码,从而提高开发效率和代码质量。

本文将详细介绍 Vue3 组合式 API 的核心概念、使用方法以及最佳实践,帮助你在实际项目中更好地利用这一强大工具。

什么是组合式 API?

组合式 API 是 Vue3 中的一种新编程模型,它允许你在 setup 函数中编写逻辑代码。与传统的选项式 API(Options API)不同,组合式 API 更加灵活,可以让你按逻辑关注点对代码进行分组,从而提高代码的可读性和可复用性。

传统组件 vs 组合式 API

在传统的选项式 API 中,所有的逻辑都集中在组件的选项对象中,例如 data、methods、computed 等。随着组件功能的增加,这种集中式的管理方式会导致代码变得冗长和难以维护。

而组合式 API 通过 setup 函数提供了一个新的入口点,你可以在其中定义响应式数据、计算属性、方法等。这种方式使得代码更加模块化,便于理解和复用。

setup 函数详解

setup 函数是组合式 API 的核心,它在组件实例化之前执行。setup 函数接收两个参数:props 和 context。

  • props:它是响应式的,当传入新的 prop 时,它会自动更新。
  • context:一个普通的 JavaScript 对象,包含了一些可能在 setup 中有用的值,如 attrs、slots、emit 等。

在 setup 函数中,你应该避免使用 this,因为它不会指向组件实例。setup 的调用发生在 data、computed 和 methods 被解析之前,因此这些选项无法在 setup 中直接访问。

示例:定义一个计数器

下面是一个简单的计数器组件示例,展示了如何使用组合式 API 定义响应式数据和方法。


<template>

<div>

<p>计数器实例: {{ count }}</p>
    <button @click="increment">点我加 1</button>
  </div>
</template>

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

export default {
  setup() {
    // 定义初始值为 0 的响应式变量
    const count = ref(0);

    // 定义点击事件处理函数
    const increment = () => {
      console.log(count.value);
      count.value += 1;
    };

    // 组件挂载时执行的生命周期钩子
    onMounted(() => {
      console.log('组件已挂载!');
    });

    // 返回需要在模板中使用的变量和方法
    return {
      count,
      increment
    };
  }
};
</script>

响应式数据管理

在组合式 API 中,你可以使用 ref 和 reactive 来创建响应式数据。

ref

ref 用于创建一个响应式的基本类型或对象。它返回一个包含 .value 属性的对象,通过 .value 来访问和修改值。

import { ref } from 'vue';

const counter = ref(0);

console.log(counter); // { value: 0 }
console.log(counter.value); // 0

counter.value++;
console.log(counter.value); // 1

reactive

reactive 用于创建一个响应式的对象。它返回一个代理对象,可以直接通过属性访问和修改值。

import { reactive } from 'vue';

const state = reactive({
  count: 0
});

console.log(state.count); // 0

state.count++;
console.log(state.count); // 1

生命周期钩子

在组合式 API 中,生命周期钩子通过带有 on 前缀的函数来实现。这些函数接受一个回调函数,当钩子被组件调用时将会执行。

示例:使用生命周期钩子

import { onBeforeMount, onMounted } from 'vue';

export default {
  setup() {
    onBeforeMount(() => {
      console.log('组件挂载前');
    });

    onMounted(() => {
      console.log('组件已挂载');
    });
  }
};

生命周期钩子映射表

Options APIComposition API
beforeCreatesetup
createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
errorCapturedonErrorCaptured

模板引用

在组合式 API 中,你可以使用 ref 来获取模板中的元素或组件实例。这些引用是响应式的,可以在组件的生命周期中动态更新。

示例:获取 DOM 元素


<template>
  <div ref="root">这是根元素</div>
</template>

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

export default {
  setup() {
    const root = ref(null);

    onMounted(() => {
      console.log(root.value); // 
<div>这是根元素</div>
    });

    return {
      root
    };
  }
};
</script>

在 v-for 中使用模板引用

在 v-for 循环中使用模板引用时,需要使用函数引用来进行自定义处理。


<template>
  <div v-for="(item, i) in list" :ref="el => { if (el) divs[i] = el }">
    {{ item }}
  </div>
</template>

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

export default {
  setup() {
    const list = reactive([1, 2, 3]);
    const divs = ref([]);

    onBeforeUpdate(() => {
      divs.value = [];
    });

    return {
      list,
      divs
    };
  }
};
</script>

侦听模板引用

你可以使用 watchEffect 或 watch 来侦听模板引用的变化。需要注意的是,这些侦听器在 DOM 更新之前运行时会有副作用,因此建议使用 flush: 'post' 选项来确保模板引用与 DOM 保持同步。

示例:使用 watchEffect 侦听模板引用


<template>
  <div ref="root">这是根元素</div>
</template>

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

export default {
  setup() {
    const root = ref(null);

    watchEffect(() => {
      console.log(root.value); // => 
<div>这是根元素</div>
    }, {
      flush: 'post'
    });

    return {
      root
    };
  }
};
</script>

组合式 API 的其他常用函数

除了上述介绍的函数外,组合式 API 还提供了许多其他有用的函数,用于管理和操作响应式数据。

computed

computed 用于创建一个基于其他响应式数据计算出的值。

import { ref, computed } from 'vue';

const count = ref(0);
const doubledCount = computed(() => count.value * 2);

watch

watch 用于观察响应式数据的变化,可以指定特定的响应式数据或计算属性。

import { ref, watch } from 'vue';

const count = ref(0);

watch(count, (newCount) => {
  console.log(newCount);
});

watchEffect

watchEffect 创建一个响应式副作用,自动追踪与其相关的响应式依赖。

import { ref, watchEffect } from 'vue';

const count = ref(0);

watchEffect(() => {
  console.log(count.value);
});

onWatcherCleanup

onWatcherCleanup 用于在观察的数据不再需要时执行清理函数。

import { ref, watch, onWatcherCleanup } from 'vue';

const count = ref(0);

watch(count, () => {
  // 清理函数
  onWatcherCleanup(() => {
    console.log('清理完成');
  });
});

总结

Vue3 的组合式 API 为开发者提供了一种更灵活、更强大的方式来组织和复用代码。通过 setup 函数,你可以按逻辑关注点对代码进行分组,从而提高代码的可读性和可维护性。本文介绍了组合式 API 的核心概念、使用方法以及一些常见的应用场景,希望对你在实际项目中使用 Vue3 提供帮助。

如果你有任何问题或建议,欢迎在评论区留言交流!