【angular】TodoList小项目(已开源)

news2024/11/18 6:33:34

参考:https://segmentfault.com/a/1190000013519099

文章目录

    • 准备工作
    • header
    • Todo、Doing、Done
      • 样式(HTML+CSS)
      • 功能(TS)
        • 将输入框内容加入todoList(addTodo)
        • 将todo事件改到doing
      • 服务
    • 参考

效果:

在这里插入图片描述

准备工作

创建项目:ng new my-app

导航到workspace 文件夹:cd my-app

启动这个项目:ng serve --open

创建组件:ng generate component component/todoList

组件的路径是:
在这里插入图片描述

创建了组件后,要把它在根组件配置(app.module.ts):

在这里插入图片描述
根据TS文件todo-list.component.ts,我们创建的todoList这个组件的名字叫做:app-todo-list。把组件引入到总页面中(app.component.html),启动服务看看。成功!到这里我们已经知道组件怎么创建和引用了。

在这里插入图片描述
接下来开始写TodoList!

header

效果:

在这里插入图片描述

<!-- todo-list.component.html -->
<header>
    <section>
        <label for="title">TodoList</label>
        <input type="text" placeholder="添加ToDo">
    </section>
</header>
/* todo-list.component.css */
header {
    height: 70px;
    background-color: #333;
}

header section{
    display: flex;
    justify-content: space-between;
}

section {
    margin: 0 auto;
    width: 70vw;
    
}

header section label {
    font-size: 28px;
    color: #fff;
    line-height: 70px;
}

header section input {
    width: 35%;
    margin: 10px 0;
    padding-left: 15px;
    border-radius: 10px;
    box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset;
}

Todo、Doing、Done

样式(HTML+CSS)

效果大致是这样:

在这里插入图片描述
一些细节

复选框与文字对齐

参考:css复选框和文字对齐-CSDN博客
在这里插入图片描述

.item .listItem input[type=checkbox] {
    width: 23px;
    height: 23px;
    /* 复选框与文字对齐 */
    display: inline-block;
    vertical-align: middle;
    margin: 0 10px 2px;
}

给Done的item设置阴影

在item外面套一层mask,设置背景黑色。item设置opacity即可。

参考:css为图片添加一层蒙版_css给图片加一层蒙版-CSDN博客

<div class="item done">
    <h2>Done</h2>
    <div class="list">
        <!-- 外面的阴影 -->
        <div class="mask">
            <div class="listItem">
                <input type="checkbox">吃饭3
            </div>        
        </div>
    </div>
</div>
.done .listItem {
    box-shadow: -5px 0 0 0 #999999;
    opacity: 0.7;
}

.done .mask {
    background: #000;
}

最终代码

<!-- todo-list.component.html -->
<header>
    <section>
        <label for="title">TodoList</label>
        <input type="text" placeholder="添加ToDo">
    </section>
</header>

<section>
    <div class="item todo">
        <h2>Todo</h2>
        <div class="list">
            <div class="listItem">
                <input type="checkbox">吃饭1
            </div>
            <div class="listItem">
                <input type="checkbox">睡觉1
            </div>
            <div class="listItem">
                <input type="checkbox">喝水1
            </div>
        </div>
    </div>
    <div class="item doing">
        <h2>Doing</h2>
        <div class="list">
            <div class="listItem">
                <input type="checkbox">吃饭2
            </div>
            <div class="listItem">
                <input type="checkbox">睡觉2
            </div>
            <div class="listItem">
                <input type="checkbox">喝水2
            </div>
        </div>
    </div>
    <div class="item done">
        <h2>Done</h2>
        <div class="list">
            <!-- 外面的阴影 -->
            <div class="mask">
                <div class="listItem">
                    <input type="checkbox" checked="checked">吃饭3
                </div>        
            </div>
        </div>
    </div>
</section>
/* todo-list.component.css */
header {
    height: 70px;
    background-color: #333;
}

header section {
    display: flex;
    justify-content: space-between;
}

section {
    margin: 0 auto;
    width: 70vw;

}

header section label {
    font-size: 28px;
    color: #fff;
    line-height: 70px;
}

header section input {
    width: 35%;
    margin: 10px 0;
    padding-left: 15px;
    border-radius: 10px;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
}

.item {
    margin: 20px 0;
}

.item h2 {
    color: #000;
    font-size: 28px;
    font-weight: 700;
    margin-bottom: 20px;
}

.item .listItem {
    background-color: #dbdbdb;
    margin: 15px 0;
    height: 40px;
    line-height: 40px;
    font-size: 16px;
}

.todo .listItem {
    box-shadow: -5px 0 0 0 #ede719;
}

.doing .listItem {
    box-shadow: -5px 0 0 0 yellowgreen;
}

.done .listItem {
    box-shadow: -5px 0 0 0 #999999;
    opacity: 0.7;
}

.done .mask {
    background: #000;
}


.item .listItem input[type=checkbox] {
    width: 23px;
    height: 23px;
    /* 复选框与文字对齐 */
    display: inline-block;
    vertical-align: middle;
    margin: 0 10px 2px;
}

功能(TS)

将输入框内容加入todoList(addTodo)

定义数据,写addTodo方法。

//todo-list.component.ts
export class TodoListComponent {
    public todo: any = '' //在input栏,即将加入todoList
    public todoList = [] as any;
    public doingList = [] as any;
    public doneList = [] as any;


	// 添加代办时间到todo
    addTodo(e: any) {
	    // 回车
	    if (e.keyCode == 13) {
	        this.todoList.push(this.todo)
	        this.todo = ''
	    }
    }
}

在html中绑定数据和时间:

输入框:

<!-- todo-list.component.html -->
<header>
    <section>
        <label for="title">TodoList</label>
        <input type="text" (keydown)="addTodo($event)" [(ngModel)]='todo' placeholder="添加ToDo">
    </section>
</header>

todoList:

<div class="item todo">
    <h2>Todo</h2>
    <div class="list">
        <div class="listItem" *ngFor="let item of todoList">
            <input type="checkbox">{{item.todo}}
        </div>
    </div>
</div>

遇到的问题与解决:

写addTodo方法:
TypeScript 错误 property does not exist on type Object - 掘金 (juejin.cn)
Parameter ‘xxx’ implicitly has an ‘any’ type的解决_implicitly has an ‘any’ type-CSDN博客

在绑定[(ngModel)]=‘todo’:解决Angular报错 Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’-CSDN博客

将todoObj push进todoList:类型“{ name: any; value: string; }”的参数不能赋给类型“never”的参数。_类型“any”的参数不能赋给类型“never”的参数_干饭了干饭了1的博客-CSDN博客

将todo事件改到doing

功能:todo打勾(点击事件),它就加到doingList中。doing到done、done到todo以此类推。

// todo 改为doing
todoChange(key: any) {
    this.doingList.push(this.todoList[key])
    this.todoList.splice(key,1)
}
<div class="item todo">
    <h2>Todo</h2>
    <div class="list">
        <div class="listItem" *ngFor="let item of todoList;let key=index">
            <input type="checkbox" (click)="todoChange(key)">{{item}}
        </div>
    </div>
</div>

刷新一下,发现页面中的数据都没了。如果想要保存页面数据,我们需要做以下操作。

服务

参考:angularcli 第七篇(service 服务) - 撑死的喵~ - 博客园 (cnblogs.com)

在控制台创建服务:

ng g service services/storage

app.module.ts中引入创建的服务:

在这里插入图片描述

在要使用的页面引入和注入服务:

在这里插入图片描述
具体服务:

可能的报错:ts报错:类型“string | null”的参数不能赋给类型“string”的参数。 不能将类型“null”分配给类型“string”。-CSDN博客

// storage.service.ts
import { Injectable } from '@angular/core';

@Injectable({
    providedIn: 'root'
})
export class StorageService {

    constructor() { }

    setItem(key: any, value: any) {
        localStorage.setItem(key, JSON.stringify(value));
    }
    getItem(key: any) {
        return JSON.parse(localStorage.getItem(key) || '')
    }
}

在每个会修改todoList、doingList、doneList的代码下面加上对应的this.storage.setItem('xx',this.xx),把数据存放在本地中。

// 添加代办时间到todo
addTodo(e: any) {
    // 回车
    if (e.keyCode == 13) {
        this.todoList.push(this.todo)
        this.todo = ''
        this.storage.setItem('todoList',this.todoList)
    }
}

// todo 改为doing
todoChange(key: any) {
    this.doingList.push(this.todoList[key])
    this.todoList.splice(key,1)
    this.storage.setItem('todoList',this.todoList)
    this.storage.setItem('doingList',this.doingList)
}

// doing 改为done
doingChange(key: any) {
    this.doneList.push(this.doingList[key])
    this.doingList.splice(key,1)
    this.storage.setItem('doneList',this.doneList)
    this.storage.setItem('doingList',this.doingList)
}

// done 改为todo
doneChange(key: any) {
    this.todoList.push(this.doneList[key])
    this.doneList.splice(key,1)
    this.storage.setItem('todoList',this.todoList)
    this.storage.setItem('doneList',this.doneList)
}

大功告成!

参考

Angular - Angular 文档简介

angularjs - 和我一起入坑,Angular入门,Angular版的ToDoList - 个人文章 - SegmentFault 思否

css复选框和文字对齐-CSDN博客

box-shadow 设置单边、多边阴影 - 掘金 (juejin.cn)

css为图片添加一层蒙版_css给图片加一层蒙版-CSDN博客

js 键盘监听(回车)_js监听键盘回车-CSDN博客

TypeScript 错误 property does not exist on type Object - 掘金 (juejin.cn)

Parameter ‘xxx’ implicitly has an ‘any’ type的解决_implicitly has an ‘any’ type-CSDN博客

angularcli 第七篇(service 服务) - 撑死的喵~ - 博客园 (cnblogs.com)

ts报错:类型“string | null”的参数不能赋给类型“string”的参数。 不能将类型“null”分配给类型“string”。-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1076614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言基础 C++

C语言基础 C 嘿&#xff0c;你想起点C基础知识&#xff0c;这是一个很好的开始&#xff01;C是一种通用的编程语言&#xff0c;被广泛用于开发各种应用程序&#xff0c;从简单的控制台程序到复杂的桌面应用和游戏开发。现在让我带你进入C的奇妙世界&#xff0c;看看它有什么特…

OBIA:900+ 患者、193w+ 影像,中科院基因组所发布我国首个生物影像共享数据库

看病就医&#xff0c;拍片已是常例。CT、核磁、X 光等影像资料可以用非侵入式手段透过人体&#xff0c;使内部器官、组织状况清晰可见&#xff0c;为临床诊断和疾病治疗提供可靠依据。 随着医学影像技术广泛发展&#xff0c;影像资料已占据国内医疗数据的 80% 以上&#xff0c…

Android平台GB28181设备接入侧如何实现SIP校时

规范解读 GB/T28181-2016规范里面&#xff0c;9.10.1章节&#xff0c;关于校时基本要求&#xff1a; 联网内设备支持基于SIP方式或 NTP方式的网络校时功能&#xff0c;标准时间为北京时间。 SIP方式校时见本节具体描述&#xff1b;NTP(见IETFRFC2030)协议的网络统一校时服务…

【通信系列 2 -- 射频电路介绍】

文章目录 1.1 射频电路介绍1.1.1 射频电路的原理1.1.2 射频电路组成和特点 1.1 射频电路介绍 射频&#xff08;RF&#xff09;是Radio Frequency的缩写&#xff0c;表示可以辐射到空间的电磁波频率&#xff0c;频率范围从300kHz&#xff5e;300GHz之间。射频就是射频电流&…

美瞳小程序经营配送商城的作用是什么

美瞳是不少小姑娘喜爱的产品&#xff0c;线上线下需求都比较旺盛&#xff0c;尤其是新款或极其漂亮的产品往往会成为疯抢的对象&#xff0c;当然市场高需求的同时商家也面临着一些难题。 通过【雨科】平台搭建美瞳商城小程序&#xff0c;将所有产品线上售卖&#xff0c;摆脱第三…

复亚智能广东智慧应急项目案例:构建“空地一体化”

近日&#xff0c;广东某区深入探索“智慧应急”发展模式&#xff0c;将无人机作为赋能应急处突与“智慧应急”的重要手段&#xff0c;利用复亚智能无人机全自动飞行系统做到“平时巡查巡检、急时辅助处突”&#xff0c;实现全面监管快速响应&#xff0c;无人机自动巡检结合多样…

Web API 基础 (Web Workers API)

Web Workers API 1、指南 1.1 使用Web Workers Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外&#xff0c;它们还可以使用XMLHttpRequest(尽管responseXML和channel属性总是为空)或fetch(没有此类限制)执…

XPS测试仪器-科学指南针

在做 X 射线光电子能谱(XPS)测试时&#xff0c;科学指南针检测平台工作人员在与很多同学沟通中了解到&#xff0c;好多同学仅仅是通过文献或者师兄师姐的推荐对XPS测试有了解&#xff0c;但是对于其测试仪器还属于小白阶段&#xff0c;针对此&#xff0c;科学指南针检测平台团队…

ant design form数组修改 关联展示

根据form 数组项修改关联其他选项 如图&#xff0c;在项目开发中&#xff0c;每个form中有多个产品&#xff0c;提货方式不同&#xff0c;有一个需要邮寄展示收货地址&#xff0c;否则不用展示 // An highlighted block <Card title"产品信息" bordered{false}&g…

VulnHub narak

一、信息收集 1.nmap扫描开发端口 2.扫描目录 利用dirb扫描目录 3.发现 /webdav目录 访问 WebDAV 基于 HTTP 协议的通信协议&#xff0c;在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法&#xff0c;使应用程序可对Web Server直接读写&#xff0c;并支持写文件锁…

vue3源码解析

vue3源码解析与前端网络安全 VUE 3 拓展 vue3 对比 vue2 响应式数据 vue2 的响应式数据是通过 Object.defineProperty 进行数据劫持&#xff0c;其存在一些缺点&#xff1a; 必须要预知劫持的 key 是什么&#xff0c;并不能很好的监听到对象属性的添加、删除&#xff1b;初…

家政服务行业怎么做微信小程序开发

随着科技的不断发展&#xff0c;微信小程序已经成为了人们生活中不可或缺的一部分。在家政服务领域&#xff0c;微信小程序也发挥出了重要的作用。本文将探讨家政服务在微信小程序上可以实现的功能。 一、展示家政服务信息 微信小程序可以作为一个展示家政服务的平台&#xff…

XML外部实体注入攻击XXE

xml是扩展性标记语言&#xff0c;来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义&#xff08;可选&#xff09;、文档元素&#xff0c;一般无法直接打开&#xff0c;可以选择用excl或记事本打…

虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序

虚拟桌宠模拟器&#xff1a;VPet-Simulator&#xff0c;一个开源的桌宠软件, 可以内置到任何WPF应用程序 虚拟桌宠模拟器 一个开源的桌宠软件, 可以内置到任何WPF应用程序 获取虚拟桌宠模拟器 OnSteam(免费) 或 通过[Nuget]内置到你的WPF应用程序 1.虚拟桌宠模拟器 详细介绍 …

2023 10月2日 至 10 月8日学习总结

学了半天 想了还是需要进行个总结 1.做的题目 NSSCTF [BJDCTF 2020]easy_md5 md5实现sql-CSDN博客 [网鼎杯 2020 白虎组]PicDown python反弹shell proc/self目录的信息_双层小牛堡的博客-CSDN博客 [CISCN2019 华北赛区 Day1 Web5]CyberPunk 二次报错注入_双层小牛堡的博客-…

XPS表征(工作原理与特点)-科学指南针

在做 X 射线光电子能谱(XPS)测试时&#xff0c;科学指南针检测平台工作人员在与很多同学沟通中了解到&#xff0c;好多同学仅仅是通过文献或者师兄师姐的推荐对XPS有了解&#xff0c;但是对于XPS测试原理还属于小白阶段&#xff0c;针对此&#xff0c;科学指南针检测平台团队组…

Laya3.0 入门教程

点击play箭头 点击右边的开发者工具 就会弹出 chrome的调试窗口 然后定位到你自己的ts文件 直接在ts里断点即可 不需要js文件 如何自动生成代码&#xff1f; 比如你打开一个新项目 里面显示的是当前场景 只需要点击 UI运行时 右边的框就可以了 他会自动弹窗提示你 创建一个文…

iNet Network Scanner for Mac,轻松管理网络

iNet Network Scanner for Mac是一款强大的网络扫描工具&#xff0c;能够帮助你轻松管理和监控网络设备。 无论你是个人用户还是企业管理员&#xff0c;iNet Network Scanner都能为你提供全面而方便的网络管理体验。它可以快速扫描并识别局域网中的所有设备&#xff0c;包括电…

竞赛选题 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…

主机加固,防勒索病毒

​近年来&#xff0c;计算机以及互联网应用在中国得到普及和发展&#xff0c;已经深入到社会每个角落&#xff0c;政府&#xff0c;经济&#xff0c;军事&#xff0c;社会&#xff0c;文化和人们生活等各方面都越来越依赖于计算机和网络&#xff0c;电子政务&#xff0c;无纸办…