JavaScript: Projeto Final: App de Tarefas

Parabéns por chegar à última lição! Ao longo das 27 lições anteriores, você aprendeu sobre variáveis, funções, arrays, DOM, eventos, JSON, programação assíncrona, classes e muito mais. Agora é hora de juntar tudo e construir uma aplicação pequena completa. Este projeto será a consolidação de tudo o que você aprendeu.


1. Visão do Projeto

Vamos construir um App de Tarefas — pode parecer simples, mas toca quase todos os conceitos que você estudou. Quando terminar, você terá uma ferramenta de produtividade real e utilizável.



▶ Exemplo

JAVASCRIPT
// Exemplo de código desta seção
const message = "Olá, Mundo!";
console.log(message);
▶ Experimente

Este é o exemplo mais simples; as seções seguintes explicarão em detalhes.## 2. Requisitos Funcionais

  1. Adicionar itens de tarefa — campo de input + botão; pressionar Enter ou clicar adiciona um novo item
  2. Alternar concluída/pendente — clicar em uma tarefa alterna seu estado (efeito de riscado)
  3. Excluir itens de tarefa — cada item tem um botão de exclusão ao lado
  4. Filtragem — três botões: Todas / Pendentes / Concluídas
  5. Armazenamento local — use localStorage para persistir dados entre atualizações da página
  6. Contar itens restantes — exiba "X itens restantes" na parte inferior


3. Requisitos Técnicos

Conceito Onde é Usado
Classe Classe AppTarefas organiza toda a lógica
async/await Envolver leitura/escrita do localStorage como funções assíncronas
Manipulação do DOM Criar itens de lista dinamicamente, atualizar conteúdo, remover elementos
Tratamento de eventos Formulário submit, lista clique, botão de filtro clique
JSON JSON.stringify para salvar, JSON.parse para carregar
Métodos de array filter, map, find para gerenciar dados de tarefas
Template literals Construir strings HTML


4. Critérios de Aceitação



5. Ideias de Implementação de Referência

Abaixo estão dicas e direções — não código completo. Escrever você mesmo é onde o aprendizado real acontece.

(1) Estrutura de Dados

HTML
<script>
// Cada item de tarefa é um objeto
const tarefa = {
  id: Date.now(),      // identificador único
  texto: 'Aprender JavaScript',
  concluida: false
};
console.log(tarefa);

// Todas as tarefas são armazenadas em um array
let tarefas = [];
</script>

(2) Estrutura da Classe

HTML
<script>
class AppTarefas {
  constructor() {
    this.tarefas = [];         // dados
    this.filtro = 'todas';     // filtro atual
    this.init();               // inicializar
  }

  async init() {
    // 1. Carregar dados do localStorage
    // 2. Vincular eventos
    // 3. Renderizar a lista
  }

  async salvar() {
    // JSON.stringify → localStorage.setItem
  }

  async carregar() {
    // localStorage.getItem → JSON.parse
  }

  adicionarTarefa(texto) { /* criar objeto, push, salvar, renderizar */ }
  alternarTarefa(id) { /* encontrar item, inverter concluida, salvar, renderizar */ }
  excluirTarefa(id) { /* filtrar item, salvar, renderizar */ }

  renderizar() {
    // 1. Filtrar tarefas com base neste.filtro
    // 2. Limpar o container da lista
    // 3. Percorrer array filtrado, criar nós DOM
    // 4. Atualizar exibição da contagem
  }
}
</script>

(3) Estratégia de Vinculação de Eventos

(4) Estratégia de Renderização

HTML
<script>
renderizar() {
  const filtradas = this.tarefas.filter(function(tarefa) {
    if (this.filtro === 'pendentes') return !tarefa.concluida;
    if (this.filtro === 'concluidas') return tarefa.concluida;
    return true;  // 'todas'
  }.bind(this));

  // Limpar o container
  this.listaEl.innerHTML = '';

  filtradas.forEach(function(tarefa) {
    var li = document.createElement('li');
    // Definir conteúdo, estilos, atributos de dados
    // Vincular eventos de alternar e excluir
    this.listaEl.appendChild(li);
  }.bind(this));

  // Atualizar a contagem
  var contagemPendentes = this.tarefas.filter(function(t) { return !t.concluida; }).length;
  this.contagemEl.textContent = contagemPendentes + ' itens restantes';
}
</script>


6. Ideias de Extensão

Quando as funcionalidades básicas estiverem funcionando, tente estes desafios avançados:



7. Tarefa

Complete o app de tarefas acima com todas as funcionalidades, e passe em todos os critérios de aceitação.

Passos sugeridos:

  1. Comece com a estrutura HTML e estilização CSS
  2. Construa o esqueleto da classe AppTarefas (constructor, init)
  3. Implemente adicionarTarefa e renderizar — faça a adição funcionar primeiro
  4. Implemente alternarTarefa — alternar concluída/pendente
  5. Implemente excluirTarefa — remover itens
  6. Implemente filtragem
  7. Implemente salvar e carregar — persistir dados
  8. Mostre a contagem de itens restantes
  9. Acabamento final: validação de input vazio, ajustes de estilo
💡 Dica: Não tente construir tudo de uma vez. Faça a menor coisa funcionar primeiro, depois adicione uma parte de cada vez. Desenvolvimento de software é "funcionar, depois ficar certo, depois ficar rápido."


▶ Exemplo

Um app Todo completo usando classes e localStorage:

HTML
<!DOCTYPE html>
<html>
<head><style>body{font-family:Arial;max-width:600px;margin:20px auto;}.done{text-decoration:line-through;color:gray;}</style></head>
<body>
  <h1>Todo App</h1>
  <input id="taskInput" placeholder="Nova tarefa">
  <button id="addBtn">Adicionar</button>
  <ul id="taskList"></ul>
  <script>
    class Todo {
      constructor() { this.tasks = JSON.parse(localStorage.getItem('tasks') || '[]'); }
      add(text) { this.tasks.push({text, done: false}); localStorage.setItem('tasks', JSON.stringify(this.tasks)); this.render(); }
      toggle(i) { this.tasks[i].done = !this.tasks[i].done; localStorage.setItem('tasks', JSON.stringify(this.tasks)); this.render(); }
      render() { document.getElementById('taskList').innerHTML = this.tasks.map((t, i) => `<li class="${t.done ? 'done' : ''}">${t.text}</li>`).join(''); }
    }
    const todo = new Todo();
    document.getElementById('addBtn').onclick = () => todo.add(document.getElementById('taskInput').value);
    todo.render();
  </script>
</body>
</html>
▶ Experimente

Demonstra um app Todo completo com gerenciamento de estado baseado em classes, persistência com localStorage e renderização dinâmica de DOM.


❓ Perguntas Frequentes

P: Por que usar Class em vez de função construtora? R: A sintaxe Class é mais limpa — constructor, this e herança têm sintaxe clara. Por baixo dos panos ainda são protótipos, mas lê como linguagens OOP e é mais fácil de manter. P: Os dados do localStorage podem ser perdidos? R: Não, o localStorage persiste até que o usuário limpe os dados do navegador ou use navegação privada. Lembre-se: só armazena strings — objetos precisam de JSON.stringify antes de salvar. P: O que é delegação de eventos e por que é útil em um app de tarefas? R: Delegação de eventos significa vincular um listener ao elemento pai e usar e.target para manipular eventos dos filhos. Novas tarefas ganham tratamento de evento automaticamente — melhor performance.

📖 Resumo


📝 Exercícios

  1. Básico: Complete as funcionalidades principais de tarefas — adicionar, alternar concluída, excluir — usando um array para armazenamento (sem precisar de localStorage).
  2. Intermediário: Adicione persistência com localStorage e filtragem (Todas / Pendentes / Concluídas) à versão básica; os dados devem sobreviver a uma atualização da página.
  3. Desafio: Implemente pelo menos uma funcionalidade de extensão (arrastar para ordenar, edição, etiquetas de categoria, troca de tema ou lembretes de prazo), e escreva uma breve explicação da sua abordagem.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%