📚 Módulo 06: Frontend - Configuração Vue 3, Vite e Rotas
Neste módulo prático, entraremos de cabeça no frontend da TecLoja 02! Utilizaremos o Vite para inicializar nossa SPA em Vue 3 com TypeScript, definiremos as interfaces de dados correspondentes aos DTOs do backend e configuraremos as rotas dinâmicas da nossa aplicação usando o Vue Router com lazy-loading.
🛠️ 1. Inicializando o Projeto Vue 3 com Vite
O Vite é a ferramenta de empacotamento moderna que substituiu o antigo Vue CLI. Ele fornece recarregamento em tempo real (Hot Module Replacement) instantâneo durante o desenvolvimento.
Passo 1: Executar o criador do Vite
No diretório do seu repositório frontend, execute o comando no terminal:
npm create vite@latest tecloja-frontend -- --template vue-ts
Passo 2: Instalar as Dependências base e utilitários
Navegue para a pasta gerada e instale as dependências essenciais:
cd tecloja-frontend
npm install
npm install vue-router@4 axios
📐 2. Mapeamento de Interfaces TypeScript (DTOs)
Para manter a consistência de dados estrita com o backend FastAPI, mapeamos a estrutura dos DTOs em interfaces TypeScript. Isso previne bugs causados por chaves nulas ou tipagens errôneas nos fluxos do Vue 3.
Crie o arquivo em src/models/index.ts:
export interface Produto {
id?: number;
nome: string;
descricao?: string;
preco: number;
estoque: number;
categoria_id: number;
categoria_nome?: string;
}
export interface CartItem {
produto_id: number;
nome: string;
preco: number;
quantidade: number;
}
export interface ItemPedidoForm {
produto_id: number;
quantidade: number;
}
export interface PedidoForm {
cliente_id: number;
itens: ItemPedidoForm[];
}
export interface UsuarioLogado {
token: string;
username: str;
papel: string;
}
🧭 3. Roteamento Lógico de Componentes com o Vue Router
O roteamento lúdico virtual permite a navegação sem recarregar o navegador. Aplicaremos a técnica de Lazy-Loading nas rotas administrativas. Com isso, os scripts da área admin só são baixados se o usuário for um administrador e clicar no link, reduzindo o tempo de carregamento inicial da loja.
flowchart TD
A[App.vue] --> B((RouterView))
B -->|/| C[Catalogo.vue]
B -->|/carrinho| D[Carrinho.vue]
B -->|/login| E[Login.vue]
B -->|/admin/...| F[Lazy Loaded Admin Views]
F -.-> G[AdminProdutos.vue]
F -.-> H[ProdutoForm.vue]
style F stroke-dasharray: 5 5
Crie o arquivo src/router/index.ts:
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
// Componentes carregados imediatamente na inicialização
import Catalogo from '../views/Catalogo.vue';
import Login from '../views/Login.vue';
import Carrinho from '../views/Carrinho.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Catalogo',
component: Catalogo
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/carrinho',
name: 'Carrinho',
component: Carrinho
},
// Rotas Administrativas com LAZY-LOADING (Otimização didática de Engenharia de Software)
{
path: '/admin/produtos',
name: 'AdminProdutos',
component: () => import('../views/admin/AdminProdutos.vue')
},
{
path: '/admin/produtos/novo',
name: 'NovoProduto',
component: () => import('../views/admin/ProdutoForm.vue')
},
{
path: '/admin/produtos/editar/:id',
name: 'EditarProduto',
component: () => import('../views/admin/ProdutoForm.vue'),
props: true // Passa o parâmetro :id dinamicamente como prop do componente
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
🚀 4. Acoplamento Inicial do Vue (src/main.ts)
Para ativar o roteador na aplicação, precisamos bindá-lo na montagem raiz da instância do Vue.
Abra e edite o arquivo src/main.ts:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import './assets/styles.css'; // Carregará o layout de estilos premium
const app = createApp(App);
app.use(router); // Habilita o Vue Router na aplicação
app.mount('#app');
Edite o componente principal src/App.vue para exibir a saída das rotas:
<template>
<div class="app-container">
<!-- O componente RouterView renderizará dinamicamente a view de acordo com a rota ativa -->
<RouterView />
</div>
</template>
<script setup lang="ts">
// Nenhuma lógica necessária no componente raiz
</script>
✅ Pré-Requisitos deste Módulo
Antes de avançar para a integração de autenticação e proteção de rotas no frontend, certifique-se de que:
- O ambiente de desenvolvimento local possui o Node.js (v18 ou superior) e o gerenciador de pacotes npm instalados.
- A API REST do backend (FastAPI + Neon PostgreSQL) desenvolvida nos módulos anteriores (01 a 05) está rodando localmente ou em produção para receber conexões.
🤔 Por que fizemos assim?
- Por que usar o Vite com TypeScript em vez do Vue CLI clássico? O Vite utiliza empacotamento nativo via módulos ES (ESM) em tempo de desenvolvimento. Isso significa que ele não precisa empacotar toda a aplicação antes de iniciar o servidor local, proporcionando Hot Module Replacement (HMR) instantâneo. O TypeScript adiciona tipagem estática opcional, permitindo capturar erros de propriedades nulas ou tipos incompatíveis durante a compilação, em vez de deixar que o usuário final sofra falhas em tempo de execução no navegador. Mapear os DTOs em interfaces TypeScript estritas garante que o frontend fale exatamente o mesmo dialeto de dados do backend FastAPI.
- Por que usar rotas dinâmicas com Lazy-Loading no Vue Router? Em SPAs (Single Page Applications) tradicionais, todo o código da aplicação é empacotado em um único arquivo JavaScript grande (bundle). Conforme o app cresce, o download desse bundle inicial pode degradar a performance percebida do usuário. O Lazy-Loading (
component: () => import(...)) instrui o empacotador (Vite/Rollup) a quebrar a aplicação em blocos de arquivos separados (code-splitting). O código da área administrativa só será baixado se, e quando, o usuário navegar para uma rota/admin, otimizando a banda e o tempo de carregamento da página principal. - Por que usar
props: truena rota de edição? Ao habilitarprops: truenas definições de rotas com parâmetros dinâmicos (como/admin/produtos/editar/:id), desacoplamos o componente de formulário do roteador do Vue. Em vez de ler diretamente$route.params.iddentro da view, o componente simplesmente declara uma prop TypeScriptid: string. Isso torna o componente reutilizável e muito mais fácil de testar isoladamente, pois ele pode receber oidvia roteamento ou diretamente de um componente pai.
🔍 Checkpoint
- Instalação Limpa: Certifique-se de que a pasta
node_modulese o arquivopackage-lock.jsonforam criados no diretóriotecloja-frontend. - Servidor Web Operando: Execute
npm run devno diretório do frontend. O terminal deve expor o link de acesso local (geralmentehttp://localhost:5173ouhttp://localhost:3000). Acesse o endereço no navegador e garanta que nenhuma mensagem de erro de compilação seja exibida no console de desenvolvedor. - Integridade do Roteamento: Tente alterar manualmente a URL do navegador para os caminhos configurados, como
/e/carrinho. A tela correspondente a cada um deles deve ser renderizada corretamente (caso já existam placeholders de arquivos correspondentes).
⚠️ Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
npm : O termo 'npm' não é reconhecido como nome de cmdlet |
O Node.js não está instalado localmente ou o caminho do binário (PATH) não foi recarregado no terminal ativo. | Baixe e instale a versão LTS do Node.js a partir do site oficial. Feche todas as instâncias do seu terminal/IDE e abra-os novamente para recarregar as variáveis de ambiente globais. |
Tela branca com erro Failed to fetch dynamically imported module no console |
O caminho do arquivo especificado no import() dinâmico do lazy-loading na configuração do router está incorreto. |
Verifique detalhadamente se a extensão dos arquivos .vue está incluída no import e se a grafia de letras maiúsculas e minúsculas bate exatamente com a estrutura física na pasta src/views/admin/. |
TypeScript acusando erro ao importar arquivos .vue |
O compilador do TypeScript não entende nativamente a extensão de arquivo Single File Component (SFC) do Vue. | Garanta que o arquivo src/vite-env.d.ts foi gerado automaticamente pelo Vite e contém a definição de módulo para interpretar arquivos .vue como componentes renderizáveis. |
🏁 Conclusão
Excelente! Nossa Single Page Application em Vue 3 está inicializada com Vite, as tipagens TypeScript estão mapeadas conforme os DTOs em Python e o roteador lógico está configurado de forma super otimizada utilizando lazy-loading.
No Módulo 07, programaremos a segurança do frontend! Criaremos o composable de autenticação useAuth usando reatividade, blindaremos as rotas administrativas contra invasões de usuários comuns e anexaremos interceptadores HTTP no Axios para injetar o cabeçalho de token Bearer de forma automatizada em todas as requisições.