Vue3: Options API vs Composition API (en)
Tags: webdev, vue, frontend, programming
Published: 2023-10-11 16:25:38

> <small>_[Ler em pt/br](https://dev.to/sucodelarangela/vue3-options-api-vs-composition-api-1j09)_</small>

Until Vue 2, we only had one way to create components, syntactically speaking. However, with [the release of **Vue 3** in 2020](https://github.com/vuejs/core/releases/tag/v3.0.0), we were introduced to a new way of organizing and reusing logic of a Vue component, the **Composition API**. Here we will focus on the main differences between the **Composition API** and the more traditional syntax of Vue 2, today known as the **Options API**.

> _**Table of Contents**
> [Options API: A Legacy from Vue 2](#options-api-a-legacy-from-vue-2)
> [Composition API: The New Thing About Vue 3](#composition-api-the-new-thing-about-vue-3)
> [But, after all, which one is the best?](#but-after-all-which-one-is-the-best)_

![Matrix pills](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxrecsedq9jrdz6hylu2.gif)

---

## Options API: A Legacy from Vue 2

When we use the **Options API** syntax, we need to create all the logic of a component within an <mark>"options object",</mark> divided into groups of properties.

Below, we list the main options in the basic logic structure with Options API, although not all of them are mandatory or necessary depending on the objective of your component:

- **data**: where we define our reactive properties (variables and states). Every property returned from `data` is exposed to the component's `this` object;
- **methods**: where we declare functions that change states and trigger updates. Methods can be used as event handlers in the template;
- **computed**: where we declare getter methods for processing and returning reactive data from our component;
- **Lifecycle Hooks**: which are built-in methods, which perform functions at different [stages of a component's life](https://vuejs.org/guide/essentials/lifecycle.html) (when it is mounted, updated, etc.).

We also have other options, such as `name`, `components`, `props`, `directives`, `watch` and `emits`, among others, but they will not be covered in this article.

Here we have a simple example of Options API, where we declare a reactive property (`value`), a method that changes `value` and a computed property that returns twice the `value`. Because they are reactive, changes are instantly rendered in the `<p>` tag. Additionally, we have a _lifecycle hook_ that will log a message to the console whenever the component is updated.

```vue
<template>
  <p>Value: {{ value }}, Double: {{ doubledValue }}</p>
  <button @click="sumValue">Click to increase the value</button>
</template>

<script>
export default {
  data() {
    return { value: 0 }
  },
  computed: {
    doubledValue () {
      return this.value * 2;
    }
  },
  methods: {
    sumValue() {
      this.value++;
    }
  },
  updated() {
    console.log(`The value now is ${this.value}`);
    console.log(`The doubled value now is ${this.doubledValue}`);
  };
};
</script>
```

In a small component like our example, the Options API seems like a good code organization alternative, with "everything in its own place". For those who started developing with Vue 2, it also has the advantage of familiarity when starting a new project or [migrating a legacy project to Vue 3](https://v3-migration.vuejs.org/).

However, in much larger components, the Options API can end up becoming a problem: the blocks of code related to each other end up being very spread out within the component's script, compromising the understanding of the logic and maintainability.

Furthermore, because it has an object-oriented syntax, the Options API also has limited support for TypeScript, which can turns things a bit more difficult for the developer.

---

## Composition API: The New Thing About Vue 3

In this new Vue 3 syntax, all component logic is defined using <mark>functions imported from the Composition API</mark> and are normally used with the `<script setup>` tag.

The `setup` attribute allows us to use the Composition API with less ["boilerplate"](https://en.wikipedia.org/wiki/Boilerplate_code) and its syntax eliminates the need to declare options in blocks, as we saw in Options API.

Below we rewrite the previous component using the Composition API:

```vue
<template>
  <p>Value: {{ value }}, Double: {{ doubledValue }}</p>
  <button @click="sumValue">Click to increase the value</button>
</template>

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

const value = ref(0);

const sumValue = () => {
  value.value++;
};

onUpdated(() => console.log(`The value now is ${value.value}`));

const doubledValue = computed(() => {
  return value.value * 2;
});

onUpdated(() => {
  console.log(`The doubled value now is ${doubledValue}`)
});
</script>
```

Let's see what differences the Composition API has brought us:

- To create a reactive property, we import and use `ref` (there is also `reactive`, used for objects);
- When changing the value of the reactive property, we use `.value`, as `ref` returns an object;
- We use a simple function (`sumValue`) to change the state without having to declare them within a prototype (like `methods` from Options API);
- We create a computed property using `computed()` to return double the value whenever it is changed;
- We also import the `onUpdated()` lifecycle, which executes a function whenever the component is updated. It is worth mentioning that, unlike the Options API, where you use the same lifecycle only once, in the Composition API a lifecycle can be called N times.

Thus, the Composition API brings us the advantage of importing only what we need into the component, instead of bringing the entire API "under the hood" (often unnecessarily), which helps to make Vue 3's performance much better than Vue 2's.

We also have more declarative and more structured code, allowing us to group it in a more logical way, as shown in the image below:

<figure>
![Code group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2z75iteuzmewnf99ppm.gif)
<figcaption>
Source: <a href='https://segmentfault.com/a/1190000040144197/en' target='_blank'>Jansen</a>
</figcaption>
</figure>
>

Furthermore, because it has a much simpler syntax, the Composition API is optimized for use with TypeScript. Another advantage is the ease of extracting and encapsulating logic, facilitating reuse and reducing code duplication (what we call [_Composable_](https://vuejs.org/guide/reusability/composables.html#what-is- a-composable)).

However, despite being designed to be simpler to implement, the Composition API may require a greater learning curve for those already used to the Options API. Furthermore, in much larger components, if your logic is not well structured, it can end up becoming unnecessarily verbose.

---

## But, after all, which one is the best?

Well, the reality is that there is no simple answer to this question. Both syntaxes are supported by **Vue 3** and both have their advantages and disadvantages. So, in the end, defining which is better or worse ends up becoming something very personal.

In general, I prefer to use the Composition API in my personal projects, due to the optimization with TypeScript and the possibility of grouping logic. However, in my day-to-day life as a developer, I use the Options API, due to syntax familiarity with Vue 2 and for the sake of code standardization between teams.

If you have only used one of the two methods so far, give the other one a try! It is even possible to use a mix of both syntaxes, using the `setup () {}` function within the Options API object! I invite you to test them in practice and discover which syntax you like best!

_See ya!_