.container{     max-width: 700px;     margin-inline: auto;     display: flex;     align-items: center;     justify-content: center;     flex-direction: column;}form #inputTodo{     padding: 8px 15px;}form #btnSubmit{     padding: 8px 15px;}.todos-container{     padding: 10px;     width: 100%;     width: fit-content;}.todo-item{     padding: 5px;     border: 1px solid gray;     gap: 20px;     width: 100%;     display: flex;     align-items: center;}.textCut{     text-decoration: line-through;}
interface Todo{     content: string,     isComplete: boolean,     readonly id:string}let todos:Todo[] = [];const todosContainer = document.querySelector(\\'.todos-container\\')!;function genrateTodo(id: string, content:string, isComplete:boolean){     const itemContainer:HTMLDivElement = document.createElement(\\'div\\');     itemContainer.classList.add(\\'todo-item\\');     // checkbox     const checkbox: HTMLInputElement = document.createElement(\\'input\\');     checkbox.type = \\\"checkbox\\\";     checkbox.checked = isComplete     checkbox.onchange = () => {          todos.find(todo => {               if(todo.id === id) todo.isComplete = checkbox.checked;               // save updated todo               localStorage.setItem(\\'todos\\', JSON.stringify(todos));          })          todoText.className = checkbox.checked ? \\'textCut\\' : \\'\\';     }     // paragraph content     const todoText:HTMLParagraphElement = document.createElement(\\'p\\');     todoText.innerHTML = content;     todoText.className = isComplete ? \\'textCut\\' : \\'\\';     // delete button     const btnDelete: HTMLButtonElement = document.createElement(\\'button\\');     btnDelete.textContent = \\'X\\';     btnDelete.onclick = () => {          todos = todos.filter(todo => todo.id !== id);          localStorage.setItem(\\'todos\\', JSON.stringify(todos));          renderTodos(todos);     }     itemContainer.append(checkbox, todoText, btnDelete);     todosContainer.appendChild(itemContainer);}// add todoconst form = document.getElementById(\\'myForm\\')!;form.onsubmit = (e: SubmitEvent) => {     e.preventDefault();     const inputElement = document.getElementById(\\'inputTodo\\') as HTMLInputElement;     let value:string = inputElement.value;     const newTodo:Todo = {          id: String(Math.random() * 1000),          content: value,          isComplete: false     }     todos.push(newTodo);     inputElement.value = \\\"\\\";     localStorage.setItem(\\'todos\\', JSON.stringify(todos));     renderTodos(todos);}function renderTodos(todos: Todo[]){     todosContainer.innerHTML = \\\"\\\";     todos.forEach(todo => {          genrateTodo(todo.id, todo.content, todo.isComplete);     })}const jsonTodos = localStorage.getItem(\\'todos\\')!;const storedTodos : Todo[] = JSON.parse(jsonTodos);todos = storedTodos;renderTodos(todos);
","image":"http://www.luping.net/uploads/20240729/172225188366a77a6bd96e6.jpg","datePublished":"2024-07-29T19:18:03+08:00","dateModified":"2024-07-29T19:18:03+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 我在 Typescript 中创建了一个 Todo 应用程序,并将 Todos 保存在本地存储中

我在 Typescript 中创建了一个 Todo 应用程序,并将 Todos 保存在本地存储中

发布于2024-07-29
浏览:136

I create a Todo Application in Typescript With Save Todos in Local Storage

我们使用带有打字稿的普通 vite 项目来理解打字稿,并使用本地存储来存储待办事项。




     
     
     
     Vite   TS
     



     

My Todo List

.container{
     max-width: 700px;
     margin-inline: auto;
     display: flex;
     align-items: center;
     justify-content: center;
     flex-direction: column;
}

form #inputTodo{
     padding: 8px 15px;
}

form #btnSubmit{
     padding: 8px 15px;
}

.todos-container{
     padding: 10px;
     width: 100%;
     width: fit-content;
}

.todo-item{
     padding: 5px;
     border: 1px solid gray;
     gap: 20px;
     width: 100%;
     display: flex;
     align-items: center;
}

.textCut{
     text-decoration: line-through;
}
interface Todo{
     content: string,
     isComplete: boolean,
     readonly id:string
}

let todos:Todo[] = [];

const todosContainer = document.querySelector('.todos-container')!;

function genrateTodo(id: string, content:string, isComplete:boolean){
     const itemContainer:HTMLDivElement = document.createElement('div');
     itemContainer.classList.add('todo-item');

     // checkbox
     const checkbox: HTMLInputElement = document.createElement('input');
     checkbox.type = "checkbox";
     checkbox.checked = isComplete
     checkbox.onchange = () => {
          todos.find(todo => {
               if(todo.id === id) todo.isComplete = checkbox.checked;

               // save updated todo
               localStorage.setItem('todos', JSON.stringify(todos));
          })
          todoText.className = checkbox.checked ? 'textCut' : '';
     }

     // paragraph content
     const todoText:HTMLParagraphElement = document.createElement('p');
     todoText.innerHTML = content;
     todoText.className = isComplete ? 'textCut' : '';

     // delete button
     const btnDelete: HTMLButtonElement = document.createElement('button');
     btnDelete.textContent = 'X';
     btnDelete.onclick = () => {
          todos = todos.filter(todo => todo.id !== id);
          localStorage.setItem('todos', JSON.stringify(todos));
          renderTodos(todos);
     }

     itemContainer.append(checkbox, todoText, btnDelete);
     todosContainer.appendChild(itemContainer);

}

// add todo
const form = document.getElementById('myForm')!;
form.onsubmit = (e: SubmitEvent) => {
     e.preventDefault();
     const inputElement = document.getElementById('inputTodo') as HTMLInputElement;
     let value:string = inputElement.value;

     const newTodo:Todo = {
          id: String(Math.random() * 1000),
          content: value,
          isComplete: false
     }

     todos.push(newTodo);
     inputElement.value = "";

     localStorage.setItem('todos', JSON.stringify(todos));

     renderTodos(todos);
}


function renderTodos(todos: Todo[]){
     todosContainer.innerHTML = "";
     todos.forEach(todo => {
          genrateTodo(todo.id, todo.content, todo.isComplete);
     })
}

const jsonTodos = localStorage.getItem('todos')!;
const storedTodos : Todo[] = JSON.parse(jsonTodos);
todos = storedTodos;
renderTodos(todos);
版本声明 本文转载于:https://dev.to/akram6t/i-create-a-todo-application-in-typescript-with-save-todos-in-local-storage-2ej3?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python 导入编解码器 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有表情符号 emoji_pattern = re.compile(“ [”...
    编程 发布于2025-01-31
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-01-31
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    [2最后一行与数据集中的每个不同标识符关联。考虑以下数据: 1 2014-02-01 kjkj 1 2014-03-11 ajskj 3 2014-02-01 sfdg 3 2014-06-12 fdsa 在(ID)上选择DISTINC 来自the_table 按ID订单,date desc;...
    编程 发布于2025-01-31
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    [2 _post ['ss'];?> 的目的是从单击提交按钮时,文本框并显示。但是,输出保持空白。当方法=“ get”无缝工作时,方法=“ post”构成问题。 检查action属性:如果您正在刷新页面,请将操作属性设置为空字符串,例如] action ='&#...
    编程 发布于2025-01-31
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式界面中实现垂直滚动元素的CSS高度限制 考虑一个布局,其中我们具有与可滚动的映射div一起移动的subollable map div用户的垂直滚动,同时保持其与固定侧边栏的对齐方式。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。 可以限制地图的滚动,我们可以利用CSS...
    编程 发布于2025-01-31
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本号的替代方法,它是使用以下语法: https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js(google hosted...
    编程 发布于2025-01-31
  • 如何在整个HTML文档中设计特定元素类型的第一个实例?
    如何在整个HTML文档中设计特定元素类型的第一个实例?
    [2单独使用CSS,整个HTML文档可能是一个挑战。 the:第一型伪级仅限于与其父元素中类型的第一个元素匹配。 以下CSS将使用添加的类样式的第一个段落: }
    编程 发布于2025-01-31
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-01-31
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2025-01-31
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    在这里工作/},false); 不幸的是,答案是否。除非在Creation中存储对处理程序的引用。要解决此问题,请考虑将事件处理程序存储在中心位置,例如页面的主要对象,请考虑将事件处理程序存储在中心位置,否则无法清理匿名事件处理程序。 。这允许在需要时轻松迭代和清洁处理程序。
    编程 发布于2025-01-31
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php 您的目标可能是检索“ varnum”属性值,其中提取数据的传统方法可能会使您感到困惑。 - > attributes()为$ attributeName => $ attributeValue){ echo $ attributeName,'=“',$ at...
    编程 发布于2025-01-31
  • 如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    [2 using the built-in CHAR_LENGTH() function.Difference between CHAR_LENGTH() and LENGTH()CHAR_LENGTH():返回字符串中字符数的数量,考虑多字节字符编码(例如,UTF-8)。 此查询将从指定的表中检...
    编程 发布于2025-01-31
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-01-31
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    解决此问题,我们采用了一个巧妙的CSS解决方案来解决问题: transform:translate:translate(-50%,-50%); height:100%; 高度:auto; 宽度:100%; //对于水平块 ,使用绝对定位将图像定位在中心,以object-fit:object-f...
    编程 发布于2025-01-31
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    </main> <section> ,但无法使其正常工作,如您所见。任何洞察力都将不胜感激! display:grid; { position:sticky; top:1em; z-index:1 1 ; { { { pos...
    编程 发布于2025-01-31

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3