Painel de Tendências em Tempo Real com Nuxt3: Implementação de Roteamento Dinâmico e Pinia

Introdução ao Projeto

Este artigo detalha a construção de um painel de monitoramento de tendências em tempo real utilizando Nuxt 3. A arquitetura foca na automação de rotas baseada no sistema de arquivos e no gerenciamento de estado centralizado com Pinia, ideal para aplicações que requerem renderização no lado do servidor (SSR) e uma estrutura modular.

  1. Configuração Inicial do Ambiente

1.1 Inicialização do Projeto Nuxt 3

Utilize o CLI oficial para iniciar um novo projeto:

npx nuxi@latest init projeto-monitor-tendencias

Após a inicialização, instale as dependências com seu gerenciador de pacotes preferido:

cd projeto-monitor-tendencias && pnpm install

1.2 Integração de Estilos e Utilitários

Para estilização, integrate o Tailwind CSS como um módulo:

pnpm add -D @nuxtjs/tailwindcss

Configure o módulo no arquivo nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@nuxtjs/tailwindcss'],
  tailwindcss: {
    configPath: '~/tailwind.config.js'
  }
})

Crie um arquivo tailwind.config.js básico para customizar o tema.

1.3 Gerenciamento de APIs e Variáveis de Ambiente

Configure um proxy de desenvolvimento no nuxt.config.ts para evitar problemas de CORS:

export default defineNuxtConfig({
  nitro: {
    devProxy: {
      '/api/tendencias': {
        target: 'https://api.dominio-externo.com',
        changeOrigin: true
      }
    }
  },
  runtimeConfig: {
    public: {
      apiBase: process.env.NUXT_API_BASE || '/api'
    }
  }
})

Defina as variáveis de ambiente no arquivo .env:

NUXT_API_BASE=https://seu-dominio-api.com/api
  1. Sistema de Roteamento Automático

2.1 Geração Dinâmica de Rotas

O Nuxt 3 gera rotas automaticamente a partir da estrutura de pastas pages/. Por exemplo:

pages/
├── index.vue            # Rota: /
├── painel/
│   ├── index.vue        # Rota: /painel
│   └── [plataforma].vue # Rota: /painel/:plataforma

No componente dinâmico, os parâmetros da rota podem ser acessados via useRoute():

<script setup>
const rota = useRoute()
const nomePlataforma = computed(() => rota.params.plataforma as string)

const { dados } = await useFetch(`/api/tendencias/${nomePlataforma.value}`)
</script>

2.2 Layouts e Middleware de Rotas

Utilize layouts para estruturar a interface. Defina um layout padrão em layouts/padrao.vue e associe-o às páginas usando definePageMeta.

Implemente middlewares globais para lógicas de autenticação:

// middleware/autenticacao.global.ts
export default defineNuxtRouteMiddleware((para, de) => {
  const storeAuth = useStoreAutenticacao()
  if (para.meta.requerLogin && !storeAuth.autenticado) {
    return navigateTo('/login')
  }
})
  1. Gerenciamento de Estado com Pinia

3.1 Estrutura do Store de Dados

Instale o Pinia e integre-o ao Nuxt 3:

pnpm add pinia @pinia/nuxt

Crie um store dedicado para as tendências. Defina interfaces e estados:

// stores/tendencias.ts
import { defineStore } from 'pinia'

interface ItemTendencia {
  identificador: string
  titulo: string
  nivelPopularidade: number
  classificacao: number
  plataforma: string
  url?: string
  atualizadoEm: number
}

interface DadosPlataforma {
  nome: string
  icone: string
  corTema: string
  lista: ItemTendencia[]
  carregando: boolean
  erro?: string
}

export const useStoreTendencias = defineStore('tendencias', () => {
  const plataformas = ref<Record<string, DadosPlataforma>>({})
  const plataformaAtiva = ref<string>('')
  const intervaloAtualizacao = ref(300000)

  const obterDadosTendencia = async (plataforma: string) => {
    const alvo = plataformas.value[plataforma]
    if (!alvo) return

    alvo.carregando = true
    try {
      const resposta = await useFetch(`/api/tendencias/${plataforma}`)
      if (resposta.data.value) {
        alvo.lista = resposta.data.value.items.map((item, idx) => ({
          identificador: `${plataforma}-${idx}`,
          titulo: item.titulo,
          nivelPopularidade: item.popularidade || 0,
          classificacao: idx + 1,
          plataforma,
          atualizadoEm: Date.now()
        }))
      }
    } catch (e) {
      alvo.erro = 'Falha ao carregar dados'
    } finally {
      alvo.carregando = false
    }
  }

  const sincronizarTodasPlataformas = async () => {
    const promessas = Object.keys(plataformas.value).map(obterDadosTendencia)
    await Promise.allSettled(promessas)
  }

  return { plataformas, plataformaAtiva, intervaloAtualizacao, obterDadosTendencia, sincronizarTodasPlataformas }
})

3.2 Uso no Componente e SSR

No componente de página, utilize o store para exibir os dados. Garanta que a inicialização ocorra no servidor para SSR:

<script setup>
const store = useStoreTendencias()

// Carregamento inicial no servidor
await store.sincronizarTodasPlataformas()
</script>

<template>
  <div v-for="(info, chave) in store.plataformas" :key="chave">
    <h3>{{ info.nome }}</h3>
    <ul v-if="!info.carregando">
      <li v-for="item in info.lista" :key="item.identificador">
        {{ item.titulo }} - Popularidade: {{ item.nivelPopularidade }}
      </li>
    </ul>
    <p v-else>Carregando...</p>
  </div>
</template>

3.3 Atualização Automática

Implemente um mecanismo de atualização periódica usando useInterval ou setInterval no lado do cliente:

<script setup>
const store = useStoreTendencias()

if (process.client) {
  const timer = setInterval(() => {
    store.sincronizarTodasPlataformas()
  }, store.intervaloAtualizacao)

  onUnmounted(() => clearInterval(timer))
}
</script>

Tags: nuxt3 vue3 pinia TailwindCSS SSR

Publicado em 7-1 19:35