DEV Community

Cover image for Vue3: Options API vs Composition API (en)
Angela Caldas
Angela Caldas

Posted on • Updated on

Vue3: Options API vs Composition API (en)

Ler em pt/br

Until Vue 2, we only had one way to create components, syntactically speaking. However, with the release of Vue 3 in 2020, 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
Composition API: The New Thing About Vue 3
But, after all, which one is the best?

Matrix pills


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 "options object", 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 (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.

<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>
Enter fullscreen mode Exit fullscreen mode

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.

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 functions imported from the Composition API and are normally used with the <script setup> tag.

The setup attribute allows us to use the Composition API with less "boilerplate" 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:

<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>
Enter fullscreen mode Exit fullscreen mode

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:

Code group

Source: Jansen

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).

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!

Top comments (2)

Collapse
 
nikita0x profile image
Nikita0x

Thank you for this great article!

Collapse
 
sucodelarangela profile image
Angela Caldas

Thanks for visiting! I'm really glad to see you enjoyed tha article! ^^