Astro 实现TodoList网页应用案例

Astro 是一个现代化的静态站点生成器和前端框架,它具有独特的设计理念:岛屿架构。它允许开发人员使用组件化的方式构建内容优先的网站,将各种技术栈(如React、Vue、Svelte等)的组件无缝集成到同一个项目中。

1、创建项目:

bash 复制代码
npm create astro@latest astro-todolist
bash 复制代码
cd astro-todolist
code .

创建组件

在 src/components/ 目录下创建 TodoList.astro

bash 复制代码
---
---

<div id="todo-app">
  <h1>TodoList</h1>
  <form id="todo-form">
    <input type="text" id="todo-input" placeholder="Add a new task">
    <button type="submit" id="add-button">Add</button>
  </form>
  <ul id="todo-list"></ul>
</div>

<script>
  const todoForm = document.getElementById('todo-form') as HTMLFormElement;
  const todoInput = document.getElementById('todo-input') as HTMLInputElement;
  const todoList = document.getElementById('todo-list') as HTMLUListElement;

  interface Todo {
    text: string;
    completed: boolean;
  }

  function loadTodos() {
    const todosJson = localStorage.getItem('todos');
    const todos: Todo[] = todosJson ? JSON.parse(todosJson) : [];
    todos.forEach(todo => {
      addTodoToDOM(todo.text, todo.completed);
    });
  }

  function saveTodos() {
    const todos: Todo[] = Array.from(todoList.children).map(li => ({
      text: li.querySelector('span')?.textContent || '',
      completed: li.classList.contains('completed')
    }));
    localStorage.setItem('todos', JSON.stringify(todos));
  }

  function addTodoToDOM(text: string, completed = false) {
    const li = document.createElement('li');
    li.className = 'todo-item' + (completed ? ' completed' : '');
    li.innerHTML = `
      <input type="checkbox" ${completed ? 'checked' : ''}>
      <span>${text}</span>
      <button class="delete-button">Delete</button>
    `;

    const checkbox = li.querySelector('input[type="checkbox"]');
    if (checkbox) {
      checkbox.addEventListener('change', function() {
        li.classList.toggle('completed');
        if (li.classList.contains('completed')) {
          todoList.appendChild(li);
        } else {
          todoList.insertBefore(li, todoList.firstChild);
        }
        saveTodos();
      });
    }

    const deleteButton = li.querySelector('.delete-button');
    if (deleteButton) {
      deleteButton.addEventListener('click', function() {
        li.remove();
        saveTodos();
      });
    }

    if (completed) {
      todoList.appendChild(li);
    } else {
      todoList.insertBefore(li, todoList.firstChild);
    }
  }

  todoForm.addEventListener('submit', function(e: Event) {
    e.preventDefault();
    if (todoInput.value.trim() === '') return;

    addTodoToDOM(todoInput.value);
    saveTodos();
    todoInput.value = '';
  });

  document.addEventListener('DOMContentLoaded', loadTodos);
</script>

<style>
 body {
      font-family: Arial, sans-serif;
    max-width: 500px;
    margin: 0 auto;
    padding: 20px;
  }
  h1 {
    text-align: center;
  }
  #todo-form {
    display: flex;
    margin-bottom: 20px;
  }
  #todo-input {
    flex-grow: 1;
    padding: 10px;
    font-size: 16px;
    border: 1px solid #ddd;
    border-radius: 4px 0 0 4px;
  }
  #add-button {
    padding: 10px 20px;
    font-size: 16px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 0 4px 4px 0;
    cursor: pointer;
  }
  #todo-list {
    list-style-type: none;
    padding: 0;
  }
  .todo-item {
    display: flex;
    align-items: center;
    padding: 10px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    margin-bottom: 10px;
    border-radius: 4px;
  }
  .todo-item.completed {
    text-decoration: line-through;
    opacity: 0.6;
  }
  .todo-item input[type="checkbox"] {
    margin-right: 10px;
  }
  .delete-button {
    margin-left: auto;
    background-color: #f44336;
    color: white;
    border: none;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
  }
</style>

创建页面

在 src/pages/index.astro 中使用 TodoList 组件:

bash 复制代码
---
import TodoList from '../components/TodoList.astro';
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Astro TodoList</title>
  </head>
  <body>
    <TodoList />
  </body>
</html>

2、运行

测试

bash 复制代码
npm run dev


构建部署

bash 复制代码
npm run build
npx netlify-cli deploy --prod


dist下打开网页:

双击静态页面打开

相关推荐
Data_Journal2 小时前
用于网页抓取的 Node-unblocker
大数据·开发语言·数据库·python·scrapy
豆角焖肉3 小时前
SSM 聚合项目搭建:多 Maven 模块项目
开发语言·python·pycharm
Frank_refuel3 小时前
【C++八股】面向对象
开发语言·c++
ly76893 小时前
HTML5 从入门到工程实践:语义化、表单、多媒体、性能与项目规范详解
前端·html·html5
m0_380743874 小时前
为 OpenAI 兼容接口配置教程
开发语言·python·node.js
万邦科技Lafite4 小时前
阿里巴巴拍立淘按图搜索商品API返回值实践:提升用户购物满意度的关键措施
开发语言·api·开放api·电商开放平台·京东开放平台
小小龙学IT5 小时前
Qt 6 跨平台开发完全指南:从信号槽机制到实际项目落地
开发语言·qt
leisoo80975 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
敢敢のwings6 小时前
智元 GO-2 与 AgiBot-World 深度解读
开发语言·后端·golang