Arquitetura e Fluxo de Dados em Aplicações Vue 3 com Vite

Estrutura Organizacional de Projetos Vue 3

O ecossistema Vue 3, aliado à ferramenta de construção Vite, estabeleceu um padrão moderno para o desenvolvimento front-end. Esta combinação oferece configurações otimizadas por padrão e uma organização de pastas que facilita a ecsalabilidade. Abaixo, detalhamos a estrutura recomendada para projetos de nível profissional.

projeto-vue/
├── node_modules/       # Dependências instaladas via npm
├── public/             # Recursos estáticos brutos (sem build processamento)
│   └── favicon.ico     # Ícone da aba do navegador
├── src/                # Diretori core da lógica
│   ├── api/            # Camada de integração com backend
│   │   └── auth.js     # Configuração Axios e endpoints de autenticação
│   ├── assets/         # Recursos importados via JS
│   │   ├── styles/     # Arquivos CSS globais e scoped
│   │   ├── imgs/       # Imagens processadas pelo Webpack/Vite
│   │   └── fonts/      # Fontes customizadas
│   ├── components/     # Componentes reutilizáveis
│   │   ├── base/       # Elementos básicos (Button, Input)
│   │   └── layout/     # Estruturas macro (Header, Sidebar)
│   ├── composables/    # Lógica encapsulada (Hooks do Vue 3)
│   │   └── useAuth.js  # Hooks para gerenciamento de login
│   ├── router/         # Definição de rotas (vue-router 4+)
│   │   └── index.js    # Mapa de rotas e guarda de navegação
│   ├── stores/         # Gerenciamento de estado global (Pinia)
│   │   └── cart.store.js # Módulo específico de carrinho
│   ├── views/          # Páginas completas associadas às rotas
│   │   ├── Dashboard/  # Página principal
│   │   │   └── index.vue
│   ├── App.vue         # Raiz da aplicação
│   ├── main.js         # Ponto de entrada e boot do framework
│   └── main.css        # Variáveis globais e reset
├── .env.local          # Variáveis de ambiente (não versionar secrets)
├── vite.config.js      # Configurações de servidor e bundling
└── package.json        # Metadados e scripts de execução

Análise dos Principais Módulos

  • src/api: Centraliza todas as requisições HTTP. Recomenda-se criar interceptores para tratamento automático de tokens JWT e erros de conexão.
  • src/composables: Diferente de componentes, estes arquivos são lógicas puras que podem ser importadas em múltiplas visões. O prefixo use é obrigatório por convenção.
  • src/stores: No Vue 3, o Pinia substitui o Vuex. Cada módulo deve refletir um domínio de negócio distinto (ex: usuário, produtos, preferências).
  • vite.config.js: Permite redirecionamentos de API (proxy) para resolver problemas de CORS durante o desenvolvimento local.

Mecanismos de Transferência de Dados entre Componentes

A comunicação no Vue ocorre principalmente através de props (descendente) e eventos (ascendente). Para cenários mais complexos, utilizam-se soluções como estado global ou injeção direta.

1. Passagem de Dados (Pai → Filho)

A técnica mais fundamental utiliza a declaração de props. O componente filho recebe dados apenas como leitura, garantindo fluxo unidirecional.

<template>
  <div class="card">
    <h2>{{ titulo }}</h2>
    <p>Status Admin:&nbsp;{{ isAdmin ? 'Sim' : 'Não' }}</p>
    <ul>
      <li v-for="item in itens" :key="item.id">{{ item.nome }}</li>
    </ul>
  </div>
</template>

<script setup>
// Definição de contratos de entrada
const props = defineProps({
  titulo: { type: String, required: true },
  itens: { 
    type: Array, 
    default: () => [] // Obrigatório usar função para arrays
  },
  isAdmin: Boolean
})
</script>

Nota-se que a modificação direta de arrays em props é desencorajada pois afeta o pai. Alterações devem sempre notificar o componente ascendente.

2. Notificação para o Acima ($emit)

Quando o componente descendente necessita disparar uma ação ou enviar informação de volta, usa-se o emit.

<template>
  <button @click="salvarRegistro">Salvar Dados</button>
</template>

<script setup>
const emit = defineEmits(['registrar-mudanca'])

const salvarRegistro = () => {
  const payload = { id: Date.now(), valor: 'novo dado' }
  emit('registrar-mudanca', payload)
}
</script>

No componente pai, o evento escuta via atributo de evento (ex: @registrar-mudanca="funcao"). Isso mantém o desacoplamento entre visão e lógica.

3. Bind Unidirecional Duplo (v-model)

Sintaxe abstrata que combina prop e evento para vincular valores em tempo real.

<!-- Parental -->
<CampoInput v-model="dadosForm" />

<script setup>
import { ref } from 'vue'
const dadosForm = ref('')
</script>

<!-- Filial -->
<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>

Para múltiplos bindings, pode-se personalizar o nome da chave usando v-model:campo="variavel" na sintaxe Vue 3.

4. Estado Global (Pinia)

A biblioteca oficial para gerenciar estado complexo elimina a necessidade de passar props por dezenas de níveis hierárquicos.

// Criação do Store
import { defineStore } from 'pinia'

export const useDadosApp = defineStore('app', {
  state: () => ({
    acessoToken: null,
    listaTarefas: []
  }),
  
  getters: {
    possuiAcesso: (state) => !!state.acessoToken
  },
  
  actions: {
    fazerLogin(token) {
      this.acessoToken = token
    }
  }
})

// Uso no Componente
import { useDadosApp } from '@/stores/main'

const store = useDadosApp()

const login = () => {
  store.fazerLogin('token_123')
}
</script>

5. Injeção de Dependência (Provide / Inject)

Útil para evitar prop drilling em árvores muito profundas. O componente ancestral fornece e os descendentes consomem.

<!-- Ancestral -->
<script setup>
import { provide, ref } from 'vue'
const corTema = ref('claro')
provide('tema', corTema)
</script>

<

Tags: vue3 pinia Vite vue-router state-management

Publicado em 10-23 05:08