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

双击静态页面打开

相关推荐
Json_1817901448012 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
傻啦嘿哟13 分钟前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光18 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
初九之潜龙勿用18 分钟前
C#校验画布签名图片是否为空白
开发语言·ui·c#·.net
风尚云网35 分钟前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
Dola_Pan35 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
ExiFengs35 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj12345678937 分钟前
JDK1.8新增特性
java·开发语言
木子020438 分钟前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing40 分钟前
React核心功能详解(一)
前端·react.js·前端框架