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下打开网页:

双击静态页面打开

相关推荐
高山我梦口香糖37 分钟前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_7482352440 分钟前
前端实现获取后端返回的文件流并下载
前端·状态模式
信号处理学渣1 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客1 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
jasmine s1 小时前
Pandas
开发语言·python
biomooc1 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人2 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
m0_748240252 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar2 小时前
纯前端实现更新检测
开发语言·前端·javascript
404NooFound2 小时前
Python轻量级NoSQL数据库TinyDB
开发语言·python·nosql