一、Vue3组合式API简介

咱先聊聊啥是Vue3组合式API。在Vue3之前呢,我们用的是选项式API,就像盖房子,把不同功能的材料放在不同房间(选项)里,比如data放数据,methods放方法。但这种方式有个问题,功能一多,代码就变得混乱,找个东西都费劲。

Vue3组合式API就不一样了,它更像是把盖房子的材料重新组合,按照功能模块来组织代码。这样代码结构更清晰,复用性也更强。

比如说,我们要做一个简单的计数器。用选项式API是这样的:

<!-- Vue选项式API示例 -->
<template>
  <div>
    <!-- 显示计数器的值 -->
    <p>Count: {{ count }}</p>
    <!-- 点击按钮增加计数器的值 -->
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 初始化计数器的值为0
      count: 0
    };
  },
  methods: {
    increment() {
      // 点击按钮时,计数器的值加1
      this.count++;
    }
  }
};
</script>

要是用组合式API呢,代码就变成这样:

<!-- Vue3组合式API示例 -->
<template>
  <div>
    <!-- 显示计数器的值 -->
    <p>Count: {{ count }}</p>
    <!-- 点击按钮增加计数器的值 -->
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
// 使用ref创建响应式数据
const count = ref(0);
// 定义增加计数器值的方法
const increment = () => {
  count.value++;
};
</script>

这里的ref是Vue3用来创建响应式数据的,就像给数据加了个“魔法”,数据一变,页面也跟着变。

二、应用场景

2.1 复杂组件开发

当我们开发复杂组件时,选项式API可能会让代码变得混乱。比如一个电商商品详情页,有商品信息、评论、推荐商品等多个功能模块。用选项式API,不同功能的代码可能会分散在不同选项里,维护起来很麻烦。

用组合式API,我们可以把每个功能模块的代码封装成一个函数,然后在组件里调用。

<!-- Vue3组合式API复杂组件示例 -->
<template>
  <div>
    <!-- 显示商品信息 -->
    <div v-if="productInfo">
      <h2>{{ productInfo.name }}</h2>
      <p>{{ productInfo.description }}</p>
    </div>
    <!-- 显示商品评论 -->
    <div v-if="comments.length > 0">
      <h3>Comments</h3>
      <ul>
        <li v-for="comment in comments" :key="comment.id">{{ comment.content }}</li>
      </ul>
    </div>
    <!-- 显示推荐商品 -->
    <div v-if="recommendedProducts.length > 0">
      <h3>Recommended Products</h3>
      <ul>
        <li v-for="product in recommendedProducts" :key="product.id">{{ product.name }}</li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
// 模拟获取商品信息的函数
const getProductInfo = () => {
  return {
    name: 'Product Name',
    description: 'This is a great product.'
  };
};
// 模拟获取商品评论的函数
const getComments = () => {
  return [
    { id: 1, content: 'Great product!' },
    { id: 2, content: 'I love it!' }
  ];
};
// 模拟获取推荐商品的函数
const getRecommendedProducts = () => {
  return [
    { id: 1, name: 'Recommended Product 1' },
    { id: 2, name: 'Recommended Product 2' }
  ];
};
// 创建响应式数据
const productInfo = ref(null);
const comments = ref([]);
const recommendedProducts = ref([]);
// 组件挂载后获取数据
onMounted(() => {
  productInfo.value = getProductInfo();
  comments.value = getComments();
  recommendedProducts.value = getRecommendedProducts();
});
</script>

2.2 代码复用

组合式API很适合代码复用。比如我们有一个表单验证的功能,在多个组件里都要用到。我们可以把验证逻辑封装成一个函数,然后在不同组件里调用。

<!-- Vue3组合式API代码复用示例 -->
<template>
  <div>
    <input v-model="username" placeholder="Username">
    <!-- 显示用户名验证错误信息 -->
    <p v-if="usernameError">{{ usernameError }}</p>
    <input v-model="password" placeholder="Password" type="password">
    <!-- 显示密码验证错误信息 -->
    <p v-if="passwordError">{{ passwordError }}</p>
    <button @click="submit">Submit</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
// 封装表单验证逻辑
const useFormValidation = () => {
  const username = ref('');
  const password = ref('');
  const usernameError = ref('');
  const passwordError = ref('');
  const validateUsername = () => {
    if (username.value.length < 3) {
      usernameError.value = 'Username must be at least 3 characters.';
    } else {
      usernameError.value = '';
    }
  };
  const validatePassword = () => {
    if (password.value.length < 6) {
      passwordError.value = 'Password must be at least 6 characters.';
    } else {
      passwordError.value = '';
    }
  };
  const submit = () => {
    validateUsername();
    validatePassword();
    if (!usernameError.value && !passwordError.value) {
      console.log('Form submitted successfully!');
    }
  };
  return {
    username,
    password,
    usernameError,
    passwordError,
    submit
  };
};
// 使用封装的表单验证逻辑
const { username, password, usernameError, passwordError, submit } = useFormValidation();
</script>

三、技术优缺点

3.1 优点

  • 代码结构清晰:组合式API按照功能模块组织代码,代码的可读性和可维护性大大提高。比如上面的复杂组件示例,每个功能模块的代码都封装在一起,一目了然。
  • 复用性强:可以把一些通用的逻辑封装成函数,在不同组件里复用。像表单验证的示例,封装的验证逻辑可以在多个表单组件里使用。
  • 更好的类型推导:在使用TypeScript时,组合式API能更好地进行类型推导,减少类型错误。

3.2 缺点

  • 学习成本较高:对于初学者来说,组合式API的概念可能比较难理解,需要一定的时间来学习和适应。
  • 过度封装可能导致代码碎片化:如果过度封装,可能会把代码拆分成很多小函数,导致代码碎片化,增加理解难度。

四、注意事项

4.1 响应式数据的使用

在组合式API里,使用refreactive创建响应式数据。ref用于创建单个值的响应式数据,reactive用于创建对象的响应式数据。要注意ref创建的数据在模板里使用时不需要.value,但在JavaScript代码里使用时需要.value

<!-- Vue3组合式API响应式数据示例 -->
<template>
  <div>
    <!-- 显示count的值,不需要.value -->
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
// 使用ref创建响应式数据
const count = ref(0);
// 定义增加计数器值的方法
const increment = () => {
  // 在JavaScript代码里使用时需要.value
  count.value++;
};
</script>

4.2 生命周期钩子的使用

组合式API里的生命周期钩子和选项式API有所不同。比如mounted在组合式API里用onMountedcreatedonBeforeMount。使用时要注意这些变化。

<!-- Vue3组合式API生命周期钩子示例 -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
// 创建响应式数据
const message = ref('');
// 组件挂载后执行的逻辑
onMounted(() => {
  message.value = 'Component is mounted!';
});
</script>

五、文章总结

Vue3组合式API为我们提供了一种全新的开发方式,告别了选项式开发的局限性。它让代码结构更清晰,复用性更强,尤其适合复杂组件开发和代码复用。虽然它有一定的学习成本,但只要掌握了它的使用方法,就能大大提高开发效率。在使用组合式API时,要注意响应式数据和生命周期钩子的使用。总之,Vue3组合式API是一个非常强大的工具,值得我们去学习和使用。