
Vue 3: Composition API ou Options API, para que serve realmente cada uma
- vuetelemetry
- Guias
- 6 min de leitura
A Composition API não substitui a Options API. Resolvem problemas diferentes em escalas diferentes, e a escolha depende menos de qual é mais recente e mais de como o seu componente cresce. O que cada uma faz, onde cada uma mostra limites e como escolher sem reescrever código que funciona.
O Vue 3 inclui as duas API. A Options API é a que o Vue sempre teve: um componente é um objeto com `data`, `computed`, `methods`, `watch` e os hooks de ciclo de vida como propriedades com nome. A Composition API, introduzida no Vue 3, permite escrever a mesma lógica como funções normais dentro de uma função `setup()` ou de um bloco `<script setup>`. Nenhuma está obsoleta e nenhuma vai desaparecer.
A Options API organiza o código por tipo de opção. Todo o estado reativo vai para `data()`. Todos os valores calculados vão para `computed`. Todos os métodos vão para `methods`. Em componentes pequenos é claro, porque cada assunto ocupa poucas linhas em cada secção e as secções percorrem-se depressa. Torna-se um problema quando o componente cresce: uma única funcionalidade (por exemplo, um filtro de pesquisa) tem o estado em `data`, os valores derivados em `computed`, os handlers de eventos em `methods` e a inicialização em `mounted`. Fica espalhada por quatro sítios do ficheiro.
Como a Options API organiza o código

A Composition API organiza o código por responsabilidade lógica. Em vez de pôr todo o estado num sítio e todos os métodos noutro, agrupa-se o estado, os valores calculados, os watchers e as funções que pertencem a uma mesma funcionalidade. Um filtro de pesquisa torna-se um bloco de 15 linhas com tudo o que precisa. A paginação torna-se outro bloco. Ficam lado a lado no ficheiro, e pode ler-se um sem saltar para outras três secções.
Isto só importa em componentes grandes. Um componente com um estado, um valor calculado e um método lê-se igualmente bem com qualquer das duas API. A Composition API começa a compensar quando um componente tem três ou mais responsabilidades independentes, porque é aí que a Options API obriga a intercalar lógica sem relação entre as secções.
Como a Composition API organiza o código
`<script setup>` é a sintaxe usada pela maior parte do código novo em Vue 3. É um atalho de compilação que dispensa escrever uma função `setup()` explícita e a respetiva instrução de retorno. As variáveis declaradas no nível superior ficam automaticamente disponíveis no template. As props declaram-se com `defineProps()` e os eventos com `defineEmits()`. Ambas são macros do compilador que não é preciso importar.
- A Options API organiza o código por tipo (data, computed, methods); a Composition API organiza-o por funcionalidade
- Nenhuma das duas API está obsoleta, e ambas usam o mesmo sistema de reatividade
- ref() é a escolha por omissão recomendada em vez de reactive(), para evitar erros de reatribuição e desestruturação
- Os composables substituem os mixins para reutilizar lógica entre componentes sem colisões de nomes
- A inferência de TypeScript funciona naturalmente com a Composition API e tem dificuldade com o this da Options API
- A migração é opcional: as duas API coexistem no mesmo projeto e até no mesmo componente
A reatividade na Composition API usa `ref()` e `reactive()`. `ref()` envolve um único valor e exige `.value` para o ler ou escrever em JavaScript (mas não no template, onde o Vue o desembrulha automaticamente). `reactive()` envolve um objeto cujas propriedades são reativas sem `.value`. A fonte de erros mais comum é esquecer `.value` no script, ou usá-lo no template, onde não é necessário.
ref, reactive e script setup
`ref()` é quase sempre a escolha por omissão certa. `reactive()` tem duas restrições que apanham muita gente. Primeiro, não se pode reatribuir o objeto inteiro (o proxy está na referência original, não na variável). Segundo, desestruturar um objeto reativo faz perder a reatividade às propriedades extraídas. `ref()` não tem nenhum dos dois problemas, e o custo de `.value` é pequeno comparado com o tempo de depuração desses casos-limite.
Os composables são a principal vantagem estrutural. Um composable é uma função que usa as primitivas da Composition API (`ref`, `computed`, `watch`, `onMounted`) e devolve estado reativo. `useMouse()`, `useFetch()` e `useLocalStorage()` são exemplos típicos. Chamam-se em `setup()` e devolvem valores reativos. É o padrão que a Options API não consegue reproduzir de forma limpa: os mixins partilham lógica entre componentes, mas fundem as propriedades pelo nome, o que cria colisões silenciosas e impede saber de onde vem uma propriedade.
Os mixins são o equivalente na Options API, e tornam-se problemáticos em grande escala. Se dois mixins definirem uma propriedade `data` com o mesmo nome, uma delas prevalece sem aviso. Se um mixin acrescentar um método, o componente não tem nenhuma declaração visível dele. A origem de uma propriedade torna-se ambígua à medida que se juntam mixins. A documentação do Vue recomenda explicitamente os composables em vez dos mixins para reutilizar lógica no Vue 3.
Composables versus mixins
O suporte a TypeScript é claramente melhor na Composition API. A Options API precisa do invólucro `defineComponent()`, e a inferência de tipos passa por um tipo `this` complexo que tem dificuldade com certos padrões (callbacks aninhados, funções externas que leem o estado do componente). A Composition API usa variáveis normais com tipos TypeScript padrão. `ref<number>(0)` dá um `Ref<number>`. Os composables têm valores de retorno tipados. A ajuda do IDE (autocompletar, tipos ao passar o rato, refatoração) funciona como em qualquer função TypeScript.
O desempenho em execução é próximo, com duas vantagens documentadas para a Composition API. O sistema de reatividade é o mesmo nos dois casos. A documentação do Vue nota que o código em `<script setup>` se minifica melhor, porque o template é compilado numa função no mesmo âmbito e os nomes das variáveis locais podem ser encurtados, enquanto o código da Options API passa por acessos a propriedades de `this`. Um projeto que use só a Composition API pode ainda desativar a Options API com a flag de compilação `__VUE_OPTIONS_API__`, que a retira do bundle de produção. Na maioria das aplicações, estes ganhos são pequenos ao lado da forma como o código está organizado.
TypeScript, desempenho e migração
A migração não é obrigatória. O Vue 3 aceita as duas API no mesmo projeto, e no mesmo ficheiro se for preciso. Um componente Options API pode usar um composable chamando-o num método `setup()` acrescentado ao lado das opções existentes. Não é preciso reescrever componentes Options API que funcionam. O caminho prático é escrever os componentes novos com `<script setup>` e refatorar os antigos só quando já os estiver a alterar por outro motivo.
Quando escolher a Options API. Componentes pequenos ou médios com lógica simples. Equipas em que a maioria dos programadores está a aprender Vue e beneficia de uma estrutura explícita. Bases de código já escritas com a Options API que não precisam de refatoração. Prototipagem rápida, quando dar nome a refs e composables atrasa mais do que a organização ajuda.
Quando escolher a Composition API. Componentes com várias responsabilidades independentes. Qualquer situação em que seja preciso partilhar lógica com estado entre componentes (os composables substituem os mixins). Projetos com TypeScript. Bibliotecas e pacotes open source (os composables são o formato de distribuição esperado). Aplicações grandes cujos ficheiros de componentes passam com frequência das 200 linhas.
FAQ
A Options API está obsoleta no Vue 3?
Não. A equipa do Vue mantém as duas API ao mesmo nível. A Options API não está obsoleta, a sua remoção não está prevista e recebe as mesmas atualizações. A documentação apresenta as duas lado a lado. Escolher a Composition API é uma decisão sobre a organização do código, não sobre estar atualizado.
Devo reescrever os meus componentes Options API com a Composition API?
Não, a menos que haja um motivo para além da própria API. Código Options API que funciona não fica pior por existir a Composition API. O mais prático é escrever os componentes novos com a Composition API e refatorar os antigos só quando já os estiver a alterar e a refatoração facilitar a mudança.
Qual é a diferença entre ref e reactive no Vue 3?
ref() envolve um único valor e exige .value para lhe aceder no script. reactive() envolve um objeto cujas propriedades são reativas sem .value. A diferença prática essencial é que reactive() perde a reatividade quando é desestruturado ou quando o objeto inteiro é reatribuído, enquanto ref() não tem nenhum dos dois problemas. A documentação do Vue e a maioria dos guias da comunidade recomendam ref() por omissão.



**O desempenho em execução é próximo, com duas vantagens documentadas para a Composition API.** O sistema de reatividade é o mesmo nos dois casos. A documentação do Vue nota que o código em `<script setup>` se minifica melhor, porque o template é compilado numa função no mesmo âmbito e os nomes das variáveis locais podem ser encurtados, enquanto o código da Options API passa por acessos a propriedades de `this`. Um projeto que use só a Composition API pode ainda desativar a Options API com a flag de compilação `__VUE_OPTIONS_API__`, que a retira do bundle de produção. Na maioria das aplicações, estes ganhos são pequenos ao lado da forma como o código está organizado.