Manual de Boas Práticas - Frontend
Estrutura de Código
-
Organize os componentes em diretórios que representem sua função
- Componentes: componentes devem ser prioritariamente visuais, sem regra de negócio. Eles devem receber informações por props e, quando necessário, emitir eventos através de emits. Exemplo:
<template>
<div class="p-4 border rounded-lg">
<h2 class="text-lg font-bold mb-2">{{ title }}</h2>
<p>{{ description }}</p>
<button @click="handleClick" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded">
Clique Aqui
</button>
</div>
</template>
<script setup>
import { defineEmits, defineProps } from 'vue';
const props = defineProps({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
}
});
const emit = defineEmits(['buttonClicked']);
const handleClick = () => {
emit('buttonClicked');
};
</script>- Views: responsáveis por receber os componentes, chamar os composables e fazer chamadas aos serviços de API.
-
Separe as responsabilidades: lógica de estado, renderização e estilização devem estar bem definidas.
-
Nomeie arquivos e componentes em PascalCase (ex.:
UserCard.vue
). Consulte a Guia de Estilo do Vue.js para mais detalhes. -
Utilize Composition API para organizar e reutilizar lógicas complexas com o uso de composables.
Arquitetura Modular
-
Divida funcionalidades em módulos claros e independentes. Cada módulo deve conter seus próprios componentes, serviços, stores (Pinia/Vuex), rotas e testes.
-
Estruture cada módulo da seguinte forma:
src/
├── modules/
│ ├── User/
│ │ ├── components/
│ │ │ └── UserProfile.vue
│ │ ├── composables/
│ │ │ └── useUser.ts
│ │ ├── store/
│ │ │ └── userStore.ts
│ │ ├── views/
│ │ │ └── UserView.vue
│ │ ├── api/
│ │ │ └── UserService.vue
│ │ ├── router.ts
│ └── Auth/
│ ├── components/
│ ├── services/
│ ├── store/
│ ├── views/ -
Evite dependências circulares entre os módulos. Se precisar compartilhar estados ou serviços, utilize uma store global ou um serviço comum.
Estilização com Tailwind CSS
-
Evite criar classes CSS, use a biblioteca sempre que possível, se não souber como escrever use a Extensão de documentação do VSCode ou peça para a IA transformar aquele estilo em classes tailwind.
-
Opte pelo uso de Contextual Sizing: os elementos filhos herdam características de tamanho e espaço baseados no contexto do elemento pai.
Exemplo com Vue e Flexbox:
<template>
<div class="flex h-full bg-gray-200">
<div class="bg-blue-500">Filho 1</div>
<div class="bg-green-500">Filho 2</div>
</div>
</template>
Exemplo com Vue e Grid:
<template>
<div class="grid grid-cols-3 gap-4 p-4 h-64 bg-gray-200">
<div class="bg-blue-500">Filho 1</div>
<div class="bg-green-500">Filho 2</div>
<div class="bg-red-500">Filho 3</div>
</div>
</template>
Nos exemplos acima, os filhos se ajustam ao espaço disponível do grid ou do flex container, sem necessidade de definir tamanhos fixos. Os elementos filhos herdam características de tamanho e espaço baseados no contexto do elemento pai.
-
Sempre consulte a documentação do Tailwind para verificar se o tamanho desejado já existe.
- Exemplo: Ao invés de definir um valor customizado para altura, verifique se
h-10
,h-12
ou valores semelhantes atendem à necessidade. - Se um valor próximo existir, alinhe com o designer para validar a utilização.
- Exemplo: Ao invés de definir um valor customizado para altura, verifique se
-
Evite o uso de
px
, prefira semprerem
.- Exemplo: Ao invés de
p-
[26px] opte porp-[1.625rem]
. - Isso facilita a escalabilidade e a adaptação em diferentes resoluções.
- Exemplo: Ao invés de
-
Minimize o uso de
width
. Caso seja realmente necessário, utilize%
ou valores emrem
para maior flexibilidade.- Exemplo: Evite
w-[300px]
, prefiraw-[50%]
ouw-[18rem]
.
- Exemplo: Evite
-
Desenvolva os componentes seguindo o conceito de Mobile First:
-
Comece definindo os estilos para telas menores, utilizando breakpoints do Tailwind para expandir para telas maiores.
-
Exemplo:
<template>
<div class="p-4 md:p-8 lg:p-12">
<p class="text-base md:text-lg lg:text-xl">
Conteúdo responsivo
</p>
</div>
</template>
-
Padrões de Código e Organização
-
Adote o padrão Early Return para evitar múltiplas condições aninhadas e tornar o código mais legível:
-
Exemplo:
function processUserData(user: User | null): void {
if (!user) return;
console.log(`Usuário: ${user.name}`);
}
-
Sempre que possível, questione: "Será que existe um Design Pattern para isso?"
-
Consulte o guia de Design Patterns para encontrar soluções elegantes e reutilizáveis:
-
Boas Práticas de Tipagem com TypeScript
- Utilize tipagem explícita sempre que possível, nunca use
any
. - Se não houver outra opção, utilize o tipo
unknown
para forçar validações explícitas.
Boas Práticas com Generics
-
Utilize Generics para criar componentes reutilizáveis e funções com tipagem flexível:
Exemplo - Array Genérico:
function getFirstElement<T>(array: T[]): T | undefined {
return array[0];
}
const firstNumber = getFirstElement<number>([1, 2, 3]); // Retorna 1
const firstString = getFirstElement<string>(['a', 'b', 'c']); // Retorna 'a' -
Evite tipagens genéricas desnecessárias. Se um tipo fixo já resolver o problema, não há necessidade de abstração.
Versionamento e Colaboração
-
Separe pequenos commits:
-
Utilize convenções de commits: Estrutura: [FLAG DO TIPO DE COMMIT] - Comentário explicando seu commit
As FLAGS dos tipos de commit são:
- feat: uma nova feature (recurso) que você está adicionando a uma aplicação específica
- fix: a resolução de um bug (geralmente nossos bugs são relacionados a um issue, seria interessante colocar o numero dele)
- style: recurso e atualizações relacionadas à estilização
- refactor: refatoração de uma seção específica da base de código
- test: tudo o que for relacionado a testes
- docs: tudo o que for relacionado à documentação
- chore: manutenção regular do código.
Exemplo de commit:
- [FIX] - Ajuste da rota de uma página com redirecionamento errado (issue #43)
- [FEAT] - Página inicial do portal de coordenador com os projetos relacionados
-
Realize PRs (Pull Requests) pequenos e objetivos para facilitar revisões.
Documentação e Comunicação
- Documente métodos complexos e componentes críticos.
- Comunique alterações significativas para a equipe com antecedência.