Finales Projekt: Mini SPA (Single Page Application)

Ziel dieses Projekts

Beende diesen Kurs mit einem Projekt, das du in deinem Portfolio zeigen kannst. Du wirst:

Schritt 1: Struktur der SPA

Erstelle ein einfaches HTML mit einem Container für Inhalte:


<nav>
  <button data-page="home">Start</button>
  <button data-page="tasks">Aufgaben</button>
</nav>

<div id="app"></div>

Schritt 2: Routing

Ansichten wechseln ohne Neuladen:


const app = document.getElementById("app");

function navigate(page) {
  if(page === "home") {
    app.innerHTML = "<h2>Willkommen zur Mini SPA</h2>";
  } else if(page === "tasks") {
    renderTasks();
  }
}

document.querySelectorAll("nav button").forEach(btn => {
  btn.addEventListener("click", () => navigate(btn.dataset.page));
});

navigate("home");

Schritt 3: Daten von API abrufen


async function fetchTasks() {
  try {
    const res = await fetch("https://jsonplaceholder.typicode.com/todos?_limit=5");
    const data = await res.json();
    state.tasks = data;
    renderTasks();
  } catch(err) {
    console.error("Fehler beim Laden der Aufgaben:", err);
  }
}

Schritt 4: State-Management


const state = {
  tasks: []
};

Schritt 5: Aufgaben rendern


function renderTasks() {
  app.innerHTML = `
    <h2>Aufgaben</h2>
    <ul>
      ${state.tasks.map(t => `
        <li>${t.title} 
          <button class="delete" data-id="${t.id}">Löschen</button>
        </li>
      `).join("")}
    </ul>
    <input id="newTask" placeholder="Neue Aufgabe"/>
    <button id="addTask">Hinzufügen</button>
  `;

  document.querySelectorAll(".delete").forEach(btn => {
    btn.addEventListener("click", () => deleteTask(btn.dataset.id));
  });

  document.getElementById("addTask").addEventListener("click", addTask);
}

Schritt 6: Hinzufügen & Löschen


function addTask() {
  const input = document.getElementById("newTask");
  if(input.value.trim() === "") return;
  
  const newTask = {
    id: Date.now(),
    title: input.value
  };
  
  state.tasks.push(newTask);
  input.value = "";
  renderTasks();
}

function deleteTask(id) {
  state.tasks = state.tasks.filter(t => t.id != id);
  renderTasks();
}

Schritt 7: Optional LocalStorage Speicher


function saveToLocalStorage() {
  localStorage.setItem("tasks", JSON.stringify(state.tasks));
}

function loadFromLocalStorage() {
  const data = localStorage.getItem("tasks");
  if(data) state.tasks = JSON.parse(data);
}

// Beim Start laden
loadFromLocalStorage();
renderTasks();

// Bei Änderungen speichern
document.addEventListener("click", saveToLocalStorage);

Übung

Versuche mehrere Seiten zu erstellen, Aufgaben dynamisch hinzuzufügen und in LocalStorage zu speichern.

Aufgabe