Projetos práticos para aprender Vue.js
Quatro projetos técnicos para consolidar a Composition API, componentização, consumo de APIs e gerenciamento de estado com Pinia — com exemplos claros, objetivos e aplicáveis.
Projeto 1 — To-do com Vue 3 (Composition API)
Um task tracker simples que utiliza reatividade, computed e o script setup para demonstrar fluxo básico de criação, marcação concluída e contagem de itens restantes.
Conceitos principais
- Reatividade com ref: acompanhar mudanças de listas e estados de tarefas.
- Computed para lógica derivada (tarefas restantes).
- Funções de manipulação (add, toggle) mantendo o estado imutável na prática.
Código mínimo
<script setup>
import { ref, computed } from 'vue';
const tasks = ref([
{ id: 1, text: 'Configurar projeto', done: false },
{ id: 2, text: 'Criar componentes básicos', done: false }
]);
const newTask = ref('');
const add = () => {
const t = newTask.value.trim();
if (!t) return;
tasks.value.push({ id: Date.now(), text: t, done: false });
newTask.value = '';
};
const toggle = (id) => {
const item = tasks.value.find(t => t.id === id);
if (item) item.done = !item.done;
};
const remaining = computed(() => tasks.value.filter(t => !t.done).length);
</script>
Observação: este pode ser o seu esqueleto para projetos futuros. Expanda com filtros, persistência local e testes unitários para evoluir o fluxo.
Projeto 2 — Card reutilizável com props e slots
Crie componentes reutilizáveis com slots para conteúdo, props para dados e estilos consistentes, aumentando a manutenibilidade do código.
InfoCard (Card.vue, conceito)
<template>
<div class="info-card">
<h4>{{ title }}</h4>
<div>
<slot name="content"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'InfoCard',
props: {
title: String
}
}
</script>
Exemplo de uso
<template>
<InfoCard title="Itens do dia">
<template v-slot:content>
<ul>
<li>Revisar pull requests</li>
<li>Atualizar dependências</li>
</ul>
</template>
</InfoCard>
</template>
<script>
import InfoCard from './InfoCard.vue';
export default { components: { InfoCard } }
</script>
Prática recomendada: crie um conjunto de cartões com data-bindings dinâmicos e slots para conteúdos variados. Utilize props para título, subtítulo e cor de tema para cada cartão.
Projeto 3 — Consumindo APIs com fetch e onMounted
Exposição de chamadas assíncronas com manejo de loading e erro, ilustrando como popular dados de uma API pública e exibir estados no template.
Código de exemplo
<script setup>
import { ref, onMounted } from 'vue';
const users = ref([]);
const loading = ref(false);
const error = ref(null);
onMounted(async () => {
loading.value = true;
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
if (!res.ok) throw new Error('Erro ao carregar dados');
users.value = await res.json();
} catch (e) {
error.value = e.message;
} finally {
loading.value = false;
}
});
</script>
O que observar
- Tratamento de estados: carregando, sucesso, erro.
- Renderização condicional com v-if/v-else.
- Uso de v-for para iterar resultados de API.
Boas práticas: isolar a lógica de fetch em composables para reutilizar em outros componentes e facilitar testes.
Projeto 4 — Dashboard simples com Pinia
Introdução ao Pinia para gerenciar estado compartilhado entre componentes, com getter para métricas e ações para mutação de dados.
Store (useTaskStore)
// store/task.js
import { defineStore } from 'pinia';
export const useTaskStore = defineStore('task', {
state: () => ({
items: []
}),
actions: {
add(text) {
this.items.push({ id: Date.now(), text, done: false });
},
toggle(id) {
const item = this.items.find(i => i.id === id);
if (item) item.done = !item.done;
}
},
getters: {
remaining: (state) => state.items.filter(i => !i.done).length
}
});
Uso no componente
// Em componente Vue
import { useTaskStore } from '@/stores/task';
const store = useTaskStore();
store.add('Nova tarefa via Pinia');
console.log(store.remaining);
Observação prática: conecte o Pinia ao Vue na inicialização da aplicação (app.use(createPinia())). O padrão facilita escalabilidade do estado conforme o projeto cresce.
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!