🤔 O que é o setup()?

O setup() é a função principal da Composition API. É onde você define e organiza a lógica reativa e a interação entre os dados e o comportamento do componente.

Como funciona o setup()?

  • O setup() é executado antes do componente ser criado, portanto, ele não tem acesso a this.
  • Ele recebe dois parâmetros:
    1. props: As propriedades do componente (como data() na Options API)
    2. context: Um objeto que fornece acesso a algumas funcionalidades internas, como attrs, slots e emit.

Dentro do setup(), você pode usar qualquer lógica reativa e retornar as variáveis e funções que você deseja expor ao template.


🧠 Compreendendo a reatividade: ref e reactive

Como funciona o ref()

  • O ref() é usado para criar valores reativos.
  • Ideal para valores primitivos (números, strings, booleans).
  • A propriedade value é usada para acessar o valor armazenado.

Exemplo com ref():

import { ref } from 'vue'

export default {
  setup() {
  const contador = ref(0)

  const incrementar = () => {
    contador.value++
  }

  return { contador, incrementar }
  }
}

No exemplo acima, o valor contador é reativo e, ao ser alterado, o Vue automaticamente atualiza a interface do usuário.

Como funciona o reactive()

  • O reactive() é usado para criar objetos ou arrays reativos.
  • Ele trabalha diretamente sobre o objeto ou array, sem a necessidade de acessar a propriedade value.

Exemplo com reactive():

import { reactive } from 'vue'

export default {
  setup() {
    const estado = reactive({
      contador: 0,
      nome: 'Vue'
    })

    const incrementar = () => {
      estado.contador++
    }

    return { estado, incrementar }
  }
}

No exemplo acima, o objeto estado é reativo, e você pode acessar ou modificar suas propriedades diretamente.

🧩 O que mais podemos fazer no setup()?

  • computed(): Cria valores derivados com base em reatividade.
  • watch(): Observa mudanças nos valores reativos e executa ações quando esses valores mudam.
  • Outros hooks de ciclo de vida: Como onMounted(), onUpdated(), onBeforeUnmount(), entre outros.

⚡ Exemplo prático: Contador simples com ref() e reactive() e computed()

import { ref, reactive, computed } from 'vue'

export default {
  setup() {
    const contador = ref(0)
    const estado = reactive({
      nome: 'Vue'
    })

    const mensagem = computed(() => {
      return `Contador: ${contador.value}`
    })

    const incrementar = () => {
      contador.value++
    }

    return { contador, estado, incrementar, mensagem }
  }
}

O que está acontecendo aqui?

  • contador é uma referência (ref) a um número, e é usado para armazenar o valor do contador.
  • estado é um objeto reativo com a propriedade nome.
  • mensagem é um valor computado que depende de contador.
  • incrementar é uma função que aumenta o valor do contador.

✅ Conclusão

  • O setup() é o coração da Composition API e é onde você vai colocar a maior parte da lógica reativa.
  • Entender o uso de ref() e reactive() é fundamental para trabalhar com dados dinâmicos e interativos.

😄 Adicional

Quando você precisa do return:

Quando você quer que variáveis ou funções definidas dentro do setup() fiquem disponíveis no seu template (ou seja, no HTML do componente), aí sim você precisa retornar elas.

<template>
   @click="incrementar">Contar: {{ contador }}
template>

<script setup>
import { ref } from 'vue'

const contador = ref(0)

function incrementar() {
  contador.value++
}
script>

⚠️ Neste exemplo usamos , que já faz o return automaticamente. Mas se você estiver usando o setup() dentro do export default, aí você precisa fazer o return manualmente:

export default {
  setup() {
    const contador = ref(0)

    function incrementar() {
      contador.value++
    }

    // Retornar para usar no template
    return { contador, incrementar }
  }
}

❌ Quando você não precisa do return:

Se você estiver criando um componente puramente lógico, como um composable (função reativa reutilizável), ou se o componente não tiver template, não precisa retornar nada pro template.

// composable: useContador.js
import { ref } from 'vue'

export function useContador() {
  const contador = ref(0)
  const incrementar = () => contador.value++
  return { contador, incrementar }
}

📌 Resumo rápido: Precisa de return no setup()?

Situação Precisa de return?
Usar variáveis ou funções no template (setup()) ✅ Sim
Usando ❌ Não (é automático)
Criando um composable (função reutilizável) ✅ Sim
Código interno sem uso no template ❌ Não