Exercícios de projeto sobre Vue.js

Estes exercícios continuam os exercícios de fixação da aula de Vue. Cada um é curto. Somados, eles montam um CRUD: criar, ler, atualizar e apagar.

Não pule. O seguinte usa o que o anterior já deixou na tela. Se travar, volte à aula indicada.

O mapa:

  1. Partes 1 a 4: CRUD na memória
  2. Parte 5: os mesmos componentes em arquivos .vue
  3. Parte 6: um projeto pronto
  4. Parte 7: o mesmo CRUD no servidor
  5. Parte 8: o mesmo CRUD, agora com despesas

Parte 1: ler

Exercício 1: três tarefas na tela

Crie uma página Vue com um array tarefas de três textos, por exemplo ["Estudar Vue", "Fazer os exercícios", "Beber água"]. Mostre cada uma com v-for num <li>.

Pronto quando as três linhas aparecerem.

Exercício 2: um componente só para mostrar

Extraia um TaskItem que recebe a tarefa por props e só escreve o texto. O pai continua com o array e o v-for.

Pronto quando a lista parecer igual, mas cada linha for um <TaskItem>.

Se travar, volte às propriedades na aula de Componentes.

Parte 2: criar

Exercício 3: botão Adicionar

No pai, coloque um <input> com v-model e um botão. Ao clicar, faça push do texto no array.

Pronto quando um texto novo aparecer no fim da lista.

Exercício 4: não aceite vazio

No mesmo método, ignore o envio se o campo estiver vazio ou só com espaços. Depois de adicionar, limpe o input.

Pronto quando clicar com o campo vazio não criar linha em branco.

Exercício 5: o formulário só avisa

Mova o input e o botão para um TaskForm. Ao enviar, o filho emite o texto. O pai ouve o evento e faz o push.

Pronto quando ainda der para adicionar, mas o input não estiver no pai.

Se travar, volte a emit na aula de Componentes.

Parte 3: apagar

Exercício 6: botão Remover no pai

No v-for, use o índice. Coloque um botão “Remover” ao lado de cada item e chame splice no array.

Pronto quando clicar e a linha sumir.

Exercício 7: quem remove é o pai, quem avisa é o filho

Passe o botão “Remover” para dentro do TaskItem. O filho emite o evento. O pai continua fazendo o splice.

Pronto quando remover ainda funcionar, agora pelo componente do item.

Parte 4: atualizar

Exercício 8: a tarefa vira um objeto

Troque cada texto do array por um objeto { texto: "Estudar Vue", feita: false }. No TaskItem, mostre só tarefa.texto. Ainda não use o campo feita.

Pronto quando a lista continuar igual, agora lendo .texto.

Exercício 9: marcar como feita

No TaskItem, um botão “Feito” emite o índice. O pai troca feita para o contrário do valor atual.

Mostre o texto diferente quando feita for verdadeiro, por exemplo com um v-if.

Pronto quando clicar e a linha mudar, e clicar de novo desfizer.

Exercício 10: o texto volta para o campo

No pai, um botão “Editar” copia tarefa.texto para o campo do formulário. Ainda não grave. Só preencha o input.

Pronto quando clicar em Editar e o texto da linha aparecer no campo.

Exercício 11: salvar no mesmo lugar

Guarde o índice da tarefa em edição. Ao enviar o formulário, se houver índice, troque o texto no array. Se não houver, continue fazendo push.

Pronto quando editar “Beber água” para “Beber suco” e a linha mudar, sem criar um item novo.

Exercício 12: editar também sai do filho

O botão “Editar” vai para o TaskItem e emite o índice. O pai entrega o texto ao TaskForm por props, e o campo já abre preenchido.

Pronto quando criar, ver, marcar como feita, editar e apagar funcionarem juntos. Isso é o CRUD em memória.

Se quiser comparar depois de tentar, use o exemplo vue-components-tasks.

Parte 5: arquivos .vue

Exercício 13: um arquivo por peça

Passe o pai, o TaskItem e o TaskForm para arquivos .vue, cada um com <template> e <script>. O comportamento da Parte 4 permanece.

Para criar o projeto, siga a parte 1 da aula de Componentes.

Pronto quando npm run dev abrir a lista e o CRUD continuar igual.

Se travar, volte aos arquivos .vue na aula de Componentes.

Parte 6: um projeto pronto

Exercício 14: só o visual

Abra o cpw2-todo no Codespace:

Open in Codespaces

npm install
npm run dev

No Task.vue, use classes do Bulma, por exemplo um card ou um box. Não mexa em mais nada neste exercício.

Pronto quando o item aparecer mais organizado na tela.

Exercício 15: carregar com async/await

No TaskApp.vue, reescreva o carregamento que está em beforeMount com async/await e try/catch. Isso é JavaScript da aula de Promise, não diretiva Vue.

Pronto quando a lista continuar aparecendo ao abrir a página.

Parte 7: o servidor

O JSON Server finge ser uma API e grava num data.json. Recarregar a página deixa de apagar os dados.

Exercício 16: o servidor no navegador

npm install -g json-server

Crie um data.json:

{
  "tasks": [
    { "id": "1", "name": "Task 1", "done": false },
    { "id": "2", "name": "Task 2", "done": false },
    { "id": "3", "name": "Task 3", "done": false }
  ]
}
json-server --watch data.json --port 3000

Abra http://localhost:3000/tasks no navegador. Ainda não ligue o Vue.

Se a porta 3000 estiver ocupada, use --port 3001.

Pronto quando o JSON das três tarefas aparecer no navegador.

Exercício 17: ler no Vue (GET)

No TaskApp, busque a lista e coloque em tarefas. Chame isso no mounted.

async carregar() {
  const response = await fetch("http://localhost:3000/tasks")
  this.tarefas = await response.json()
}

Não grave nada ainda.

Pronto quando as três tarefas do arquivo aparecerem na sua lista.

Exercício 18: criar no servidor (POST)

JSON.stringify vira o objeto em texto JSON, que é o que o servidor entende.

async criar(tarefa) {
  const response = await fetch("http://localhost:3000/tasks", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(tarefa)
  })
  const salva = await response.json()
  this.tarefas.push(salva)
}

Pronto quando adicionar uma tarefa, dar F5 e ela continuar lá.

Exercício 19: apagar no servidor (DELETE)

async apagar(id) {
  await fetch("http://localhost:3000/tasks/" + id, {
    method: "DELETE"
  })
  this.tarefas = this.tarefas.filter((tarefa) => tarefa.id !== id)
}

Pronto quando apagar, dar F5 e a tarefa não voltar.

Exercício 20: atualizar no servidor (PUT)

Ao editar o texto ou marcar como feita, envie a tarefa inteira:

async atualizar(tarefa) {
  await fetch("http://localhost:3000/tasks/" + tarefa.id, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(tarefa)
  })
}

Pronto quando editar, dar F5 e a mudança continuar. Aí o CRUD está no servidor também.

Parte 8: a mesma ideia, outro assunto

Agora despesas, não tarefas. Cada despesa tem id, descricao, categoria e valor.

Faça na mesma ordem: ler, criar, apagar, atualizar.

Exercício 21: listar despesas

Monte um despesas.json (ou um data.json com a chave despesas) com duas ou três despesas e mostre a lista com GET.

Pronto quando os dados do arquivo aparecerem na tela.

Exercício 22: cadastrar despesa

Formulário com descrição, categoria e valor. POST no servidor. A lista atualiza.

Pronto quando cadastrar, dar F5 e a despesa continuar.

Exercício 23: excluir despesa

Botão para DELETE pelo id.

Pronto quando apagar, dar F5 e ela não voltar.

Exercício 24: editar despesa

Um botão “Editar” preenche o formulário. Ao salvar, PUT no servidor.

Pronto quando mudar o valor, dar F5 e a mudança continuar. Isso fecha o CRUD de despesas.

Exercício 25: o total

Some os valor e mostre o total gasto na tela.

Pronto quando cadastrar duas, ver a soma certa, apagar uma e o total cair.

Exercício 26: três componentes

Separe o que já funciona:

  1. ExpenseList mostra a lista
  2. ExpenseForm cadastra e edita
  3. SummaryCard mostra o total

Pronto quando a tela fizer a mesma coisa, agora em três peças.

Rodrigo Prestes Machado
CC BY 4.0 DEED

Copyright © 2026 RPM Hub. Distributed by CC-BY-4.0 license.

This site uses Just the Docs, a documentation theme for Jekyll.