💻 Exemplos: Capítulo 01: Ecossistema Vue 3, Vite, SFCs (.vue) e Composition API
Especialização em Front-End com Vue • Demonstrações Práticas Compiláveis
💻 Código de Exemplo 01 — SFC Moderno com Vite, <script setup> e TypeScript
O exemplo abaixo demonstra a anatomia canônica de um Single File Component (SFC) no Vue 3 utilizando Vite, TypeScript estrito e a Composition API com <script setup>.
<!-- src/components/UserMetricCard.vue -->
<script setup lang="ts">
import { ref, computed } from 'vue';
// Definição de contrato de tipos para a métrica corporativa
interface MetricPayload {
id: string;
label: string;
value: number;
threshold: number;
unit: string;
}
// Estado reativo encapsulado via ref
const metric = ref<MetricPayload>({
id: 'srv-cpu-01',
label: 'Utilização de CPU do Cluster',
value: 42.5,
threshold: 80.0,
unit: '%'
});
const isUpdating = ref<boolean>(false);
// Propriedade computada para inferência de status de saúde
const isCritical = computed<boolean>(() => {
return metric.value.value >= metric.value.threshold;
});
const statusBadgeClass = computed<string>(() => {
return isCritical.value
? 'badge-danger bg-red-600 text-white'
: 'badge-success bg-emerald-600 text-white';
});
// Ação de simulação de telemetria em tempo real
function simulateMetricUpdate(): void {
isUpdating.value = true;
setTimeout(() => {
// Variação pseudoaleatória entre -10% e +15%
const delta = (Math.random() * 25) - 10;
const newValue = Math.max(0, Math.min(100, metric.value.value + delta));
metric.value.value = Number(newValue.toFixed(1));
isUpdating.value = false;
}, 400);
}
</script>
<template>
<div class="metric-card border rounded-xl p-6 shadow-sm bg-white max-w-md">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-bold text-slate-800">{{ metric.label }}</h3>
<span :class="['px-2.5 py-1 rounded-full text-xs font-semibold uppercase', statusBadgeClass]">
{{ isCritical ? 'Crítico' : 'Normal' }}
</span>
</div>
<div class="metric-value-wrapper my-4">
<span class="text-4xl font-extrabold text-slate-900">{{ metric.value }}</span>
<span class="text-xl text-slate-500 font-medium ml-1">{{ metric.unit }}</span>
</div>
<div class="w-full bg-slate-200 rounded-full h-2.5 mb-4 overflow-hidden">
<div
class="h-2.5 rounded-full transition-all duration-500"
:class="isCritical ? 'bg-red-500' : 'bg-emerald-500'"
:style="{ width: `${metric.value}%` }"
></div>
</div>
<button
type="button"
:disabled="isUpdating"
@click="simulateMetricUpdate"
class="w-full py-2.5 px-4 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white font-medium transition-colors disabled:opacity-50"
>
{{ isUpdating ? 'Recebendo Telemetria...' : 'Atualizar Métrica Agora' }}
</button>
</div>
</template>
<style scoped>
.metric-card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.metric-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
</style>
🖥️ Saída / Comportamento Esperado
Ao carregar no navegador via Vite dev server (npm run dev):
[VITE v5.x] Ready in 180 ms.
Local: http://localhost:5173/
Estado Inicial:
Card: "Utilização de CPU do Cluster"
Badge: "NORMAL" (bg-emerald-600)
Valor: 42.5 %
Barra de progresso: 42.5% preenchida
Ao clicar em "Atualizar Métrica Agora":
Botão muda para "Recebendo Telemetria..." (disabled)
Após 400ms:
Valor atualizado para 83.2%
Badge reativo altera instantaneamente para "CRÍTICO" (bg-red-600)
Barra de progresso cresce com transição suave CSS.
🔍 Destaques da Implementação
- Compilador SFC (
<script setup>): O código é compilado diretamente para a funçãorender(), eliminando overhead de closures em tempo de execução. - Reatividade Granular: O acesso a
metric.valuerastreia dependências apenas nas propriedades lidas durante a renderização do template. - Escopo de Estilo Isolado: A tag
<style scoped>injeta automaticamente um atributo identificador (ex:data-v-7ba5bd90) nos nós HTML para evitar vazamento de CSS.