Vue.js: Propriedades Computadas
Última atualização: 2026-10-20
As propriedades computadas (computed) são propriedades especiais do Vue 3 que são recalculadas automaticamente com base em dados reativos. Seu principal valor está no armazenamento em cache — elas só são recalculadas quando os dados dependentes mudam; caso contrário, simplesmente retornam o valor anterior. Compreender as propriedades computadas é fundamental para escrever aplicativos Vue de alto desempenho.
No cerne das propriedades computadas estão três características fundamentais: rastreamento automático de dependências + armazenamento em cache dos resultados + reatividade. Esta aula vai ajudá-lo a dominar seus cinco casos de uso e a evitar suas três armadilhas.
1. O que você vai aprender
computed()Sintaxe básica e valores de retorno- Principais diferenças entre propriedades calculadas e métodos (armazenamento em cache)
- Propriedades calculadas bidirecionais com getter e setter
- Chamadas encadeadas a propriedades calculadas (calculadas dentro de outras propriedades calculadas)
- Diferentes usos de “computed” em modelos e métodos
- 3 armadilhas comuns (uso indevido, dependências circulares, problemas de desempenho)
2. Um problema de desempenho relacionado ao preço total do carrinho de compras
(1) Problema: 100 produtos são recalculados a cada clique
Alice criou o cálculo do total do carrinho no painel de administração do seu site de comércio eletrônico:
// ❌ The "Broken" Version: Use methods
function cartTotal(items) {
console.log('Calculating...') // Print on every call
return items.reduce((sum, item) => sum + item.price * item.quantity, 0)
}
<template>
<div>
<p>Total: ${{ cartTotal(items) }}</p>
<p>Tax: ${{ cartTotal(items) * 0.08 }}</p>
<p>Grand Total: ${{ cartTotal(items) * 1.08 }}</p>
<button @click="showDate = new Date()">Update Time</button>
</div>
</template>
O desempenho é péssimo:
- Carregamento da página: o cálculo é executado 1 vez ✅
- Calcular uma vez: 3 vezes (Total, Imposto, Total Geral) = 300 cálculos de itens
- O usuário clica em “Atualizar hora” (sem relação com os itens): 0 alterações, mas o cálculo ainda é executado 3 vezes = 300 cálculos de itens
A ferramenta de monitoramento de desempenho mostra:
“A função
cartTotalé chamada 5.000 vezes a cada carregamento da página. 100 itens × 5.000 = 500.000 cálculos item por item. Aplacação de 3 segundos.”
(2) Solução com computados do Vue: Armazenamento em cache + rastreamento de dependências
import { ref, computed } from 'vue'
const items = ref([
{ price: 100, quantity: 2 },
{ price: 50, quantity: 1 }
])
// ✅ computed:Rely solely on items,items If it hasn't changed, don't recalculate it.
const cartTotal = computed(() => {
console.log('Calculating...') // Only at items Print when changes occur
return items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
})
// computed Auto-Processing 3 For use in: Count only 1 time
const tax = computed(() => cartTotal.value * 0.08)
const grandTotal = computed(() => cartTotal.value * 1.08)
(3) Receita
Após mudar para “computed”:
- Chamadas de função: 5.000 → 100 (-98%)
- Tempo até a interação: 3 s → 80 ms (-97%)
- Travamento durante a rolagem: 5/s → 0 (-100%)
- Utilização da CPU: 80% → 5% (-94%)
3. Uso básico da função computed()
(1) Sintaxe padrão
import { ref, computed } from 'vue'
const count = ref(0)
// Basic Computational Properties
const doubleCount = computed(() => {
return count.value * 2
})
// Abbreviation
const doubleCount = computed(() => count.value * 2)
// Usage
console.log(doubleCount.value) // 0
count.value = 5
console.log(doubleCount.value) // 10
(2) Uso em modelos
No modelo, {{ doubleCount }} não é obrigatório .value (descompactado automaticamente).
(3) 5 Principais Características
graph TB
subgraph ComputedKey Features
A[Automatic Dependency Tracking]
B[Cache Results]
C[Responsive]
D[Lazy Evaluation]
E[Chainable calls]
end
style A fill:#42b883,color:#fff
style B fill:#42b883,color:#fff
style C fill:#42b883,color:#fff
style D fill:#42b883,color:#fff
style E fill:#42b883,color:#fff
| Recurso | Descrição |
|---|---|
| Rastreamento automático de dependências | Detecta automaticamente os dados reativos utilizados no corpo das funções |
| Resultados em cache | Acessos múltiplos contam como apenas 1 quando as dependências permanecem inalteradas |
| Responsivo | Recalcula automaticamente quando as dependências mudam |
| Avaliação preguiçosa | Não é avaliada a menos que seja acessada (economiza desempenho) |
| Encadeável | o valor da propriedade computada pode depender de outras propriedades computadas |
4. Computed vs. métodos: 5 diferenças principais
| Aspecto | calculado | métodos |
|---|---|---|
| Armazenamento em cache | ✅ Não há recálculo se as dependências permanecerem inalteradas | ❌ Recalcula a cada chamada |
| Responsivo | ✅ Rastreia dependências automaticamente | ❌ Não rastreia (requer a passagem manual de parâmetros) |
| Acesso ao modelo | {{ doubleCount }} |
{{ doubleCount() }} |
| Parâmetros | ❌ Não suportado | ✅ Aceita qualquer parâmetro |
| Casos de uso | Valores derivados simples | Lógica complexa, tratamento de eventos |
(4) 5 cenários à sua escolha
| Cenário | Usando valores calculados | Usando métodos |
|---|---|---|
| Duplique o número exibido | ✅ | ❌ |
| Calcular o valor total do carrinho | ✅ | ❌ |
| Processar clique no botão | ❌ | ✅ |
| Enviar solicitação de API | ❌ | ✅ |
| Formatação de data (sem dependências) | ❌ | ✅ |
| Lista de filtros (depende dos dados) | ✅ | ❌ |
| Validação do formulário | ❌ | ✅ |
▶ Exemplo: Comparação entre computados e métodos
// ❌ methods:Recalculate on every call
function getTotal() {
console.log('Calculated!') // If used multiple times in the template, it will be printed multiple times.
return items.value.reduce((sum, i) => sum + i.price * i.quantity, 0)
}
// ✅ computed: Count only 1 time
const total = computed(() => {
console.log('Calculated!') // Print Only 1 time
return items.value.reduce((sum, i) => sum + i.price * i.quantity, 0)
})
Saída:
getTotal() usado 3x no template → console: Calculated! 3x
computed total usado 3x → console: Calculated! 1x
Itens alterados → recalcula 1x, mesmo com vários usos
5. Getter/Setter: Propriedades calculadas bidirecionais
(1) Por padrão, existe apenas um getter
const firstName = ref('Alice')
const lastName = ref('Smith')
// There is only one getter
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
console.log(fullName.value) // Alice Smith
// fullName.value = 'Bob Lee' // ❌ Warning:Calculated properties are read-only.
(2) Getters e setters completos
const firstName = ref('Alice')
const lastName = ref('Smith')
const fullName = computed({
// Read:Put it together
get() {
return `${firstName.value} ${lastName.value}`
},
// Write:Unpack
set(newValue) {
const parts = newValue.split(' ')
firstName.value = parts[0]
lastName.value = parts[1] || ''
}
})
// ✅ Read and write access is now available
fullName.value = 'Bob Lee'
console.log(firstName.value) // Bob
console.log(lastName.value) // Lee
(3) Vinculação bidirecional em modelos
▶ Exemplo: getters + setters
▶ ExperimenteSaída:
First: Alice
Last: Smith
O input mostra "Alice Smith"
Digite "Bob Jones" → First: Bob, Last: Jones
6. Chamadas encadeadas para propriedades calculadas
(1) Cálculos aninhados
const items = ref([
{ price: 100, quantity: 2 },
{ price: 50, quantity: 3 }
])
// First Floor:Total Original Price
const subtotal = computed(() =>
items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
)
// Second Floor: Tax (Based on subtotal)
const tax = computed(() => subtotal.value * 0.08)
// Third Floor: Discount (Based on subtotal)
const discount = computed(() => subtotal.value > 200 ? 20 : 0)
// Fourth Floor:Final Total Price
const total = computed(() => subtotal.value + tax.value - discount.value)
console.log(total.value) // 350 * 1.08 - 20 = 358
(2) Mecanismo de cache com cálculo em cadeia
graph TB
A[items change] --> B[subtotal Recalculate]
B --> C[tax Recalculate]
B --> D[discount Recalculate]
C --> E[total Recalculate]
D --> E
style A fill:#42b883
style B fill:#42b883
style E fill:#42b883
Apenas os valores calculados que dependem da cadeia serão recalculados; os que não forem utilizados não serão recalculados.
▶ Exemplo: Chamadas em cadeia calculadas
import { ref, computed } from 'vue'
const score = ref(85)
// First Floor:Base Score
const baseScore = computed(() => score.value)
// Second Floor:Bonus Points(Base Score × Difficulty Level)
const difficultyBonus = computed(() => {
if (baseScore.value >= 90) return 10
if (baseScore.value >= 80) return 5
return 0
})
// Third Floor:Level
const grade = computed(() => {
const total = baseScore.value + difficultyBonus.value
if (total >= 95) return 'A+'
if (total >= 90) return 'A'
if (total >= 80) return 'B'
return 'C'
})
Saída:
score = 85 → baseScore = 85, difficultyBonus = 5, grade = "A"
score = 95 → difficultyBonus = 10, grade = "A+"
Alterar score recalcula apenas a cadeia afetada
7. Exercício abrangente: preço total do carrinho de compras
▶ Exemplo: Cálculo básico
▶ ExperimenteSaída:
Subtotal: $1099
Tax (8%): $87.92
Discount: -$50
Total: $1136.92
(1) 📊 5. Cinco cenários de comparação de desempenho
| Cena | Número de métodos chamados | Número de chamadas calculadas |
|---|---|---|
| Usado 1 vez no modelo | 1 | 1 |
| Usado 3 vezes no modelo | 3 | 1 |
| Usado 10 vezes no modelo | 10 | 1 |
| O componente pai é atualizado, mas os itens permanecem inalterados | Recuperado | Não recalculado |
| Alterações nas dependências | Revogação | Recálculo |
(2) 📊 6. 5 erros comuns
| Erro | Sintoma | Solução |
|---|---|---|
| Substituir métodos por expressões calculadas | Baixo desempenho com uso repetido | Mudar para expressões calculadas |
Passagem incorreta de parâmetros para computed |
Erro | computed não aceita parâmetros; use methods em vez disso |
| setter: Escreva o seu próprio | Loop infinito | setter: Modifique a dependência; não use fullName.value = ... |
| Dependência circular A→B→A | Loop infinito | Remova uma das dependências |
| Lógica complexa escrita em propriedades calculadas | Difícil de depurar | Extraia para um método; faça com que a propriedade calculada chame o método |
❓ Perguntas Frequentes
computed ou methods?computed sempre que possível (armazenamento em cache + rastreamento automático). Use methods apenas nas seguintes situações: (1) quando precisar passar parâmetros; (2) quando não depender de dados reativos; (3) para manipuladores de eventos (@click, etc.).computed pode aceitar parâmetros?computed só pode ter 0 parâmetros. Se você precisar passar parâmetros, use o methods em vez disso: getDouble(n) { return n * 2 }, ou faça com que o computed retorne uma função: computed(() => (n) => n * 2).computed fora de setup?computed retorna um objeto ref, que pode ser passado para outros componentes ou funções. No entanto, para manter a reatividade, recomenda-se usar computed como uma “referência derivada”.computed e watch?computed é um “valor derivado” (cálculo de um novo valor com base em dados), enquanto watch é um “observador” (execução de efeitos colaterais quando os dados mudam). computed é adequado para cálculos puros, enquanto watch é adequado para fazer solicitações, definir estado e assim por diante.computed tem melhor desempenho do que o methods?methods executa a função a cada chamada, enquanto o computed só é executado quando suas dependências mudam. No modelo, usar o computed três vezes resulta em apenas um cálculo; usar o methods resulta em três cálculos.fullName deve atualizar firstName e lastName, e não fullName.value = ....computed pode ser assíncrono?computed é síncrono; use watch ou watchEffect para operações assíncronas. Se você precisar de “propriedades calculadas assíncronas”, use a combinação de data() { return { result: null } } e watch + onMounted.📖 Resumo
computedé uma “referência derivada” que se recalcula automaticamente com base em dados reativos. Possui cinco características principais: rastreamento automático, armazenamento em cache, reatividade, avaliação preguiçosa e encadeabilidade.{{ doubleCount }}no modelo não requer .value (desempacotamento automático);doubleCount.valueem JS- computed vs métodos: os computed armazenam em cache (desempenho), enquanto os métodos não armazenam em cache, mas aceitam parâmetros
- Propriedades computadas bidirecionais com getter/setter: legíveis e graváveis; o setter atualiza as dependências, mas não se atualiza a si mesmo
- Chamadas em cadeia em propriedades calculadas: uma propriedade calculada pode depender de outras propriedades calculadas; propriedades calculadas não utilizadas não são recalculadas.
- 3 armadilhas: dependências circulares, uso indevido de métodos e lógica complexa que dificulta a depuração
- Desempenho: A propriedade
computedé usada em três lugares no modelo, mas é avaliada apenas uma vez, enquantomethodsé avaliada três vezes.
📝 Exercícios
-
Questões básicas (Dificuldade: ⭐)
Escreva uma propriedade computada
wordCountque conte o número de palavras em um trecho de texto (usandosplitpara dividir o texto por espaços).Dados:
const text = ref('Hello Vue 3 from Alice')Deveria exibir 4. -
Problemas avançados (Dificuldade: ⭐⭐)
Escreva um cálculo do total do carrinho de compras que inclua três propriedades calculadas:
subtotal: A soma do preço e da quantidade de todos os itensdiscount: Economize 10 em pedidos de 100 ou mais; economize 30 em pedidos de 200 ou maistotal: subtotal - desconto- 3 itens: iPhone $999 × 1, capa $50 × 2, carregador $30 × 1
-
Problema de desafio (Dificuldade: ⭐⭐⭐)
Implementar um “sistema completo de cálculo do total do carrinho de compras”:
- 5 produtos, cada um com nome, preço e quantidade
- subtotal / imposto (8%) / desconto (20 de desconto para compras de 200 ou mais) / total — 4 valores calculados
- Use getters e setters para a propriedade calculada
fullName; no setter, atualizefirstNameelastNamecom base na entrada. - Testar o rastreamento de dependências para 5 propriedades calculadas (quais são recalculadas após a modificação de qualquer produto)
- Use o Mermaid para desenhar um gráfico de dependências para propriedades calculadas