Vue3: Options API vs Composition API (pt/br)

Angela Caldas - Sep 4 '23 - - Dev Community

Read it in English

Até o Vue 2, só tínhamos uma maneira de se criar componentes, sintaticamente falando. Porém, com a chegada do Vue 3 em 2020, fomos apresentados a uma nova forma de organizar e reutilizar a lógica de um componente Vue, a Composition API. Aqui vamos focar nas principais diferenças entre a Composition API e a forma mais tradicional do Vue 2, hoje conhecida como Options API.

Sumário
Options API: herança do Vue 2
Composition API: a novidade do Vue 3
Mas, afinal, qual a melhor?

Pílulas de Matrix


Options API: herança do Vue 2

Quando usamos a sintaxe da Options API, precisamos criar toda a lógica de um componente dentro de um "objeto de opções", dividido em grupos de propriedades.

Abaixo, listamos as principais opções na estrutura básica da lógica com Options API, apesar de nem todas serem obrigatórias ou necessárias dependendo do objetivo do seu componente:

  • data: onde definimos nossas propriedades reativas (variáveis e estados). Toda propriedade retornada de data fica exposta ao this do componente;
  • methods: onde declaramos funções que alteram estados e disparam atualizações. Métodos podem ser usados como event handlers no template;
  • computed: onde declaramos métodos getters para tratamento e retorno de dados reativos do nosso componente;
  • Lifecycle Hooks: que são métodos built-in de ciclo de vida, que executam funções em diferentes estágios da vida de um componente (quando ele é montado, atualizado, etc).

Temos também outras opções, como name, components, props, directives, watch e emits, entre outras, mas podemos falar um pouco mais sobre eles em um artigo futuro.

Aqui temos um exemplo simples de Options API, onde declaramos uma propriedade reativa (valor), um método que altera valor e uma propriedade computada que retorna o dobro de valor. Por serem reativas, as alterações são instantaneamente renderizadas na tag <p>. Além disso, temos um lifecycle hook que registrará no console uma mensagem sempre que o componente for atualizado.

<template>
  <p>Valor: {{ valor }}, Dobro: {{ valorEmDobro }}</p>
  <button @click="somaValor">Clique para aumentar o valor</button>
</template>

<script>
export default {
  data() {
    return { valor: 0 }
  },
  computed: {
    valorEmDobro () {
      return this.valor * 2;
    }
  },
  methods: {
    somaValor() {
      this.valor++;
    }
  },
  updated() {
    console.log(`O valor agora é ${this.valor}`);
    console.log(`O valor em dobro agora é ${this.valorEmDobro}`);
  };
};
</script>
Enter fullscreen mode Exit fullscreen mode

Em um componente pequeno como nosso exemplo, a Options API parece uma boa alternativa de organização de código, com "cada coisa no seu quadrado". Para quem já vem do desenvolvimento com Vue 2, ela também tem a vantagem da familiaridade ao iniciar um novo projeto ou migrar um projeto legado para o Vue 3.

No entanto, em componentes bem maiores, a Options API pode acabar se tornando um problema: os blocos de códigos relacionados entre si acabam ficando muito espalhados dentro do script do componente, prejudicando a compreensão da lógica e a manutenibilidade.

Além disso, por ter uma sintaxe voltada para a orientação de objetos, a Options API também tem suporte limitado para o uso com TypeScript, dificultando a vida do desenvolvedor.


Composition API: a novidade do Vue 3

Na Composition API, toda a lógica do componente é definida usando funções importadas da API de Composição e são, normalmente, utilizadas com a tag <script setup>.

O atributo setup nos permite utilizar a API de Composição com menos "boilerplate" e a sua sintaxe dispensa a declaração de opções em blocos, como vimos na Options API.

Abaixo vamos reescrever o componente anterior utilizando a Composition API:

<template>
  <p>Valor: {{ valor }}, Dobro: {{ valorEmDobro }}</p>
  <button @click="somaValor">Clique para aumentar o valor</button>
</template>

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

const valor = ref(0);

const somaValor = () => {
  valor.value++;
};

onUpdated(() => console.log(`O valor agora é ${valor.value}`));

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

onUpdated(() => {
  console.log(`O valor em dobro agora é ${valorEmDobro}`)
});
</script>
Enter fullscreen mode Exit fullscreen mode

Vamos ver o que a Composition API nos trouxe de diferente?

  • Para criar uma propriedade reativa, importamos e utilizamos ref (há também o reactive, utilizado para objetos);
  • Ao mudar o valor da propriedade reativa, usamos .value, pois ref retorna um objeto;
  • Usamos uma função simples (somaValor) para alterar o estado sem precisar declará-las dentro de um protótipo como methods;
  • Criamos uma propriedade computada utilizando computed() para retornar o dobro do valor sempre que este for alterado;
  • Também importamos o ciclo de vida onUpdated(), que executa uma função sempre que o componente for atualizado. Vale ressaltar que, diferente da Options API, onde você usa o mesmo ciclo de vida apenas uma vez, na Composition API um ciclo de vida pode ser chamado N vezes.

Com isso, a Composition API traz a vantagem de importarmos apenas o que necessitamos dentro do componente, em vez de trazer "por baixo dos panos" toda a API (muitas vezes sem necessidade), o que ajuda a tornar a performance do Vue 3 bem melhor que a do Vue 2.

Também temos um código mais declarativo e mais estruturado, permitindo que possamos agrupar código de forma mais lógica, como demonstra a imagem abaixo:

Agrupamento de código

Fonte: Jansen

Além disso, por possuir uma sintaxe bem mais simples, a Composition API é otimizada para uso com TypeScript. Uma outra vantagem é a facilidade de extrair e encapsular lógica, facilitando o reuso e diminuindo a duplicação de código (o que chamamos de Composable).

No entanto, apesar de ter sido desenvolvida para ser mais simples de implementar, a Composition API pode exigir uma curva maior de aprendizado para quem já está acostumado com a Options API. Além disso, em componentes muito maiores, se a sua lógica não for bem estruturada, pode acabar se tornando mais verbosa desnecessariamente.


Mas, afinal, qual a melhor?

Bom, a realidade é que não há uma resposta simples pra essa pergunta. Ambas as sintaxes são suportadas pelo Vue 3 e ambas possuem suas vantagens e desvantagens. Então, no fim das contas, definir qual a melhor ou pior acaba se tornando algo bem pessoal.

Mas falando em pessoalidade, no geral, eu prefiro usar a Composition API em meus projetos pessoais, pela otimização com o TypeScript e pela possibilidade de agrupar as lógicas. No entanto, no meu dia-a-dia como desenvolvedora, utilizo a Options API, pela familiaridade de sintaxe com o Vue 2 e por questão de padronização de código entre as squads.

Se você, até agora, só utilizou uma das duas formas, experimente! É possível até mesmo usar um mix de ambas as sintaxes, utilizando a função setup () {} dentro do objeto de opções da Options API! Te convido à testar na prática e descobrir qual sintaxe mais te agrada!

Um xero!

. . . . . . . . . . . . . . . . . . .
Terabox Video Player