在 Vue 中,选项式 API(Options API)组合式 API(Composition API) 是两种不同的编写组件逻辑的方式。它们的主要区别体现在代码组织、逻辑复用和灵活性上。以下是它们的详细对比:

1. 语法风格

  • 选项式 API
  • 传统 Vue 组件写法,使用一组选项(如 datamethodscomputedwatch 等)来定义组件的状态、逻辑和行为。
  • 每个选项都有自己专门的部分,逻辑上比较直观,但会让相关逻辑散布在不同的选项中。

示例:

export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  },
  computed: {
    doubleCount() {
      return this.count * 2;
    }
  }
}
  • 组合式 API
  • 引入自 Vue 3,使用 setup 函数来组合逻辑,允许开发者将与某一功能相关的代码组合在一起,不再受选项划分的限制。
  • 提供更灵活的逻辑组织方式,特别适合复杂应用中的代码复用和模块化。

示例:

import { ref, computed } from 'vue';

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

    return { count, increment, doubleCount };
  }
}

2. 代码组织

  • 选项式 API
  • 代码按照功能类型组织:data 定义数据,methods 定义方法,computed 定义计算属性等。
  • 缺点是当组件逻辑复杂时,相关功能的代码可能分散在不同的选项块中,不易于维护。

**例子:**当一个功能涉及到 datamethods 时,它们分别存在于不同的部分中,阅读或维护时需要在这些部分之间跳转。

  • 组合式 API
  • 代码按照逻辑功能来组织,将相关逻辑(状态、方法、计算属性等)集中在一起,更加模块化。
  • 优点是当组件逻辑复杂时,相关的代码可以紧密组织在一起,易于维护和复用。

3. 逻辑复用

  • 选项式 API
  • 如果需要复用逻辑,通常依赖于 mixinsVue.extend,但 mixins 有命名冲突和逻辑来源不明确的问题。
  • 多个 mixins 可能导致代码变得复杂,不利于清晰的逻辑结构。
  • 组合式 API
  • 提供了 composables(可组合函数)的方式,将逻辑封装成函数,方便在多个组件之间复用。
  • 没有 mixins 的复杂性,逻辑清晰且灵活。

示例:创建一个可复用的计数逻辑:

// useCounter.js
import { ref } from 'vue';

export function useCounter() {
  const count = ref(0);
  const increment = () => count.value++;
  return { count, increment };
}

// 在组件中使用
import { useCounter } from './useCounter';

export default {
  setup() {
    const { count, increment } = useCounter();
    return { count, increment };
  }
}

4. TypeScript 支持

  • 选项式 API
  • 虽然可以与 TypeScript 配合使用,但由于各个选项部分是分开的,因此对类型推断和类型检查的支持相对较弱。
  • 复杂项目中使用 TypeScript 时,可能需要大量手动注释类型。
  • 组合式 API
  • 与 TypeScript 有更好的集成,尤其是在 setup 函数中,使用类型推断和显式类型声明非常自然。
  • 因为逻辑是集中在函数中,类型声明可以直接在函数参数和返回值中体现,类型推断更加准确和灵活。

5. 生命周期钩子

  • 选项式 API
  • 生命周期钩子直接定义为组件选项,如 mountedcreated 等。

示例:

export default {
  mounted() {
    console.log('Component mounted');
  }
}
  • 组合式 API
  • setup 函数中使用生命周期钩子 API,比如 onMountedonUpdated 等。

示例:

import { onMounted } from 'vue';

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

6. 可读性和学习曲线

  • 选项式 API
  • 对于 Vue 初学者来说更直观,因为它以明确的选项块组织代码,结构清晰,易于理解。
  • 适合中小型项目或功能相对简单的应用。
  • 组合式 API
  • 对于初学者来说可能有一定的学习曲线,因为 setup 函数中将所有逻辑集中在一起,代码组织更加灵活。
  • 适合大型项目或功能复杂的应用,代码复用性更好。

7. 灵活性

  • 选项式 API
  • 相对固定的结构,在开发简单应用时足够使用,但面对复杂逻辑,复用和扩展较为困难。
  • 组合式 API
  • 提供了极大的灵活性,开发者可以按照功能模块自由组织代码,特别适合拆分复杂业务逻辑、增强代码可复用性。

总结

特性

选项式 API

组合式 API

语法风格

通过选项(datamethodscomputed 等)

通过 setup 函数组织逻辑,灵活自由

代码组织

逻辑分散到不同选项块,直观但分散

逻辑可以集中,适合复杂应用

逻辑复用

通过 mixins 实现,但存在命名冲突问题

通过组合函数复用逻辑,灵活且清晰

TypeScript 支持

支持但较为局限

原生支持更好,类型推断更精确

生命周期钩子

使用选项 mountedcreated

setup 中使用 onMounted 等 API

学习曲线

易于上手,适合初学者

需要一些学习成本,但适合复杂项目

适用场景

小型项目,逻辑简单

中大型项目,逻辑复杂,代码复用性强

  • 选项式 API 更适合新手和简单项目,代码逻辑较为直观和易维护。
  • 组合式 API 提供了更强的灵活性和复用能力,特别适合大型项目和复杂的业务逻辑。