Vue 3 Reactivity Transform em 2026: $ref, $computed e Perguntas de Entrevista

Guia completo sobre Reactivity Transform do Vue 3, incluindo $ref, $computed, macros de reatividade e perguntas frequentes em entrevistas técnicas.

Vue 3 Reactivity Transform com $ref e $computed

O Reactivity Transform do Vue 3 representa uma evolução significativa na forma como desenvolvedores trabalham com reatividade. Essa funcionalidade experimental, introduzida para simplificar a sintaxe do Composition API, passou por várias iterações antes de alcançar sua forma atual em 2026. Compreender seu funcionamento, vantagens e limitações constitui um conhecimento essencial para qualquer desenvolvedor Vue que busca dominar os conceitos avançados do framework.

Estado do Reactivity Transform em 2026

O Reactivity Transform foi oficialmente estabilizado no Vue 3.5. As macros $ref, $computed e $shallowRef estão disponíveis através de um plugin dedicado do Vite, separado do core do Vue.

Entendendo o Problema que o Reactivity Transform Resolve

O Composition API padrão do Vue 3 exige o uso de .value para acessar e modificar valores reativos criados com ref(). Essa sintaxe, embora explícita, introduz uma carga cognitiva adicional e pode gerar bugs sutis quando o desenvolvedor esquece de usar .value.

typescript
import { ref, computed } from 'vue'

// Sintaxe padrão do Composition API
const count = ref(0)
const doubled = computed(() => count.value * 2)

function increment() {
  count.value++ // .value necessário
}

console.log(doubled.value) // .value necessário também

O Reactivity Transform elimina essa necessidade transformando automaticamente o código em tempo de compilação. As variáveis declaradas com macros de reatividade se comportam como variáveis JavaScript normais enquanto conservam sua natureza reativa.

As Macros $ref e $computed

As macros $ref e $computed constituem o núcleo do Reactivity Transform. Elas permitem declarar valores reativos sem a necessidade de manipular .value manualmente.

vue
<script setup>
// Com Reactivity Transform
let count = $ref(0)
const doubled = $computed(() => count * 2)

function increment() {
  count++ // Não precisa de .value
}

console.log(doubled) // Acesso direto
</script>

<template>
  <button @click="increment">{{ count }} (doubled: {{ doubled }})</button>
</template>

O compilador do Vue transforma esse código para sintaxe padrão com ref() e .value antes da execução. Essa transformação é transparente para o desenvolvedor e não modifica o comportamento do código.

Como Funciona a Transformação

O compilador analisa o código e aplica as seguintes transformações:

  1. $ref(value) se torna ref(value)
  2. Os acessos à variável se tornam variable.value
  3. As atribuições se tornam variable.value = newValue
typescript
// Código fonte com Reactivity Transform
let message = $ref('Olá')
message = 'Tchau'
console.log(message)

// Código transformado pelo compilador
const message = ref('Olá')
message.value = 'Tchau'
console.log(message.value)

Configuração do Reactivity Transform com Vite

A ativação do Reactivity Transform requer uma configuração específica no projeto Vue. Em 2026, essa funcionalidade é fornecida através do plugin @vue/reactivity-transform.

vite.config.tstypescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { reactivityTransform } from '@vue/reactivity-transform'

export default defineConfig({
  plugins: [
    vue(),
    reactivityTransform()
  ]
})

Para projetos que utilizam TypeScript, uma configuração adicional garante o reconhecimento dos tipos das macros.

tsconfig.jsonjson
{
  "compilerOptions": {
    "types": ["@vue/reactivity-transform"]
  }
}

$shallowRef e Outras Macros Avançadas

Além de $ref e $computed, o Reactivity Transform inclui outras macros para casos de uso específicos.

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

// $shallowRef para objetos grandes
let largeObject = $shallowRef({ data: [], metadata: {} })

// Apenas a referência é reativa, não as propriedades internas
largeObject = { data: [1, 2, 3], metadata: { updated: true } }

// $toRef para converter uma prop em ref
const props = defineProps<{ initialValue: number }>()
let value = $(props.initialValue) // Equivalente a toRef(props, 'initialValue')

watchEffect(() => {
  console.log('Value changed:', value)
})
</script>

A Macro $() para Desestruturação Reativa

A macro $() permite desestruturar objetos reativos enquanto preserva a reatividade de cada propriedade extraída.

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

const state = reactive({
  firstName: 'João',
  lastName: 'Silva',
  age: 30
})

// Desestruturação com preservação de reatividade
const { firstName, lastName } = $(state)

// firstName e lastName continuam reativos
function updateName() {
  firstName = 'Pedro' // Modifica state.firstName
}
</script>

Integração com Composables

O Reactivity Transform se integra naturalmente com composables, simplificando seu uso e criação.

composables/useCounter.tstypescript
export function useCounter(initial = 0) {
  let count = $ref(initial)
  const doubled = $computed(() => count * 2)
  const isEven = $computed(() => count % 2 === 0)

  function increment() {
    count++
  }

  function decrement() {
    count--
  }

  function reset() {
    count = initial
  }

  // $$() converte as refs para objetos ref padrão no retorno
  return $$({ count, doubled, isEven, increment, decrement, reset })
}

O uso do composable se torna mais intuitivo.

vue
<script setup>
import { useCounter } from '@/composables/useCounter'

// Desestruturação com $() para manter a reatividade
const { count, doubled, increment, reset } = $(useCounter(10))
</script>

<template>
  <div>
    <p>Count: {{ count }} (Doubled: {{ doubled }})</p>
    <button @click="increment">+</button>
    <button @click="reset">Reset</button>
  </div>
</template>

Gerenciamento de Props com Reactivity Transform

A conversão de props para refs reativas modificáveis localmente representa um caso de uso frequente do Reactivity Transform.

vue
<script setup>
const props = defineProps<{
  modelValue: string
  disabled?: boolean
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

// Criação de uma ref local vinculada à prop
let localValue = $ref(props.modelValue)

// Sincronização bidirecional
watch(
  () => props.modelValue,
  (newVal) => { localValue = newVal }
)

watch(
  () => localValue,
  (newVal) => { emit('update:modelValue', newVal) }
)
</script>

<template>
  <input v-model="localValue" :disabled="disabled" />
</template>

Perguntas de Entrevista Técnica sobre Reactivity Transform

As entrevistas técnicas de Vue 3 frequentemente incluem perguntas sobre Reactivity Transform. As seguintes perguntas representam os tópicos mais comumente abordados.

Pergunta 1: Qual é a diferença entre $ref e ref?

Resposta esperada: $ref é uma macro de compilação que gera código usando ref() com acesso automático a .value. A diferença é puramente sintática no nível do código fonte. Em tempo de execução, ambos produzem o mesmo resultado. $ref melhora a ergonomia do desenvolvedor eliminando a necessidade de escrever .value manualmente.

Pergunta 2: Por que usar $$() ao retornar valores de um composable?

Resposta esperada: A macro $$() converte as variáveis transformadas pelo Reactivity Transform em objetos ref padrão. Sem essa conversão, os valores retornados seriam primitivas que perderiam sua reatividade. $$() garante que o consumidor do composable receba refs reativas que pode usar com $() para desestruturação.

Pergunta 3: O Reactivity Transform funciona com Options API?

Resposta esperada: Não. O Reactivity Transform foi projetado exclusivamente para o Composition API com <script setup>. Ele se baseia na análise estática do código em tempo de compilação, o que não é compatível com a estrutura dinâmica do Options API.

Pergunta 4: Como depurar código que usa Reactivity Transform?

Resposta esperada: O código fonte visível nas ferramentas de desenvolvimento é o código transformado, não o código original. Para depurar efetivamente, recomenda-se usar source maps e compreender a transformação aplicada. O Vue DevTools exibe corretamente os valores reativos independentemente da sintaxe utilizada.

typescript
// Para ver a ref subjacente durante a depuração
let count = $ref(0)
console.log($$(count)) // Exibe o objeto ref completo

Pergunta 5: Quais são as armadilhas comuns do Reactivity Transform?

Resposta esperada: As armadilhas principais incluem:

  • Esquecer $$() ao retornar valores de funções
  • Misturar sintaxe padrão e sintaxe transformada no mesmo arquivo
  • Assumir que todas as operações JavaScript funcionam identicamente (algumas atribuições complexas podem requerer atenção especial)
  • Não configurar corretamente o TypeScript para reconhecer os tipos das macros

Comparação com a Sintaxe Padrão

Uma comparação direta ilustra as diferenças entre as duas abordagens.

vue
<!-- Sem Reactivity Transform -->
<script setup>
import { ref, computed, watch } from 'vue'

const items = ref<string[]>([])
const filter = ref('')
const filteredItems = computed(() =>
  items.value.filter(item => item.includes(filter.value))
)

function addItem(item: string) {
  items.value.push(item)
}

watch(filter, (newFilter) => {
  console.log('Filter changed:', newFilter)
})
</script>
vue
<!-- Com Reactivity Transform -->
<script setup>
import { watch } from 'vue'

let items = $ref<string[]>([])
let filter = $ref('')
const filteredItems = $computed(() =>
  items.filter(item => item.includes(filter))
)

function addItem(item: string) {
  items.push(item)
}

watch($$(filter), (newFilter) => {
  console.log('Filter changed:', newFilter)
})
</script>

Pronto para mandar bem nas entrevistas de Vue.js / Nuxt.js?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Boas Práticas e Recomendações

A adoção do Reactivity Transform em um projeto existente requer uma abordagem metódica para manter a consistência do código.

Consistência dentro do projeto: Escolher uma abordagem (padrão ou transformada) e aplicá-la uniformemente. Misturar as duas sintaxes complica a leitura e manutenção do código.

Documentação explícita: Documentar o uso do Reactivity Transform no README do projeto e guias de contribuição. Novos desenvolvedores devem compreender a sintaxe utilizada.

Testes unitários: Os testes funcionam identicamente independentemente da sintaxe utilizada, já que o código é transformado antes da execução. Não são necessárias modificações nos testes existentes durante a migração.

Migração progressiva: Para projetos existentes, migrar arquivo por arquivo em vez de converter tudo simultaneamente. Essa abordagem reduz o risco de introduzir bugs.

O Reactivity Transform representa uma melhoria significativa na ergonomia do desenvolvimento com Vue 3. Seu domínio demonstra uma compreensão profunda do sistema de reatividade do Vue e constitui uma vantagem em entrevistas técnicas para posições de desenvolvedor Vue sênior.

Desafio do dia

Você saberia encontrar o bug em Vue.js / Nuxt.js?

Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador da SharpSkill

Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.

Atualizado em 9 de setembro de 2026

Tags

#vue 3
#reactivity transform
#composition api
#entrevista técnica

Compartilhar

Artigos relacionados