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

  1. Compilador SFC (<script setup>): O código é compilado diretamente para a função render(), eliminando overhead de closures em tempo de execução.
  2. Reatividade Granular: O acesso a metric.value rastreia dependências apenas nas propriedades lidas durante a renderização do template.
  3. 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.