react学习——17react中todoList案列

1、项目目录
在这里插入图片描述
2、App.js

//创建“外壳”组件APP
import React, {Component} from "react";
//引入Header组件
import Header from "./components/Header";
//引入List组件
import List from "./components/List";
//引入Footer组件
import Footer from "./components/Footer";
//引入样式
import "./App.css";
//创建并暴露App组件
export default class App extends Component {
    //状态在哪里,操作状态的方法就在哪里
    state={
        todos:[
            {id:1,name:'吃饭',done:true},
            {id:2,name:'睡觉',done:false},
            {id:3,name:'打代码',done:true},
            {id:4,name:'逛街',done:false},
        ]
    }
    //用于添加todo ,接收的参数是todo对象
    addTodo=(todoObj)=>{
        const {todos} = this.state;
        //追加一个todo
        const  newTodos = [todoObj,...todos];
        //更新状态
        this.setState({todos:newTodos})
    }
    //用于更新todo
    updateTodo=(id,done)=>{
        //获取状态中的todos
        const {todos} = this.state;
        //匹配处理数据
        const newTodos = todos.map((todoObj)=>{
            if (todoObj.id===id) return {...todoObj,done}
            else return todoObj
        })
        this.setState({todos:newTodos})
    }
    //deleteTodo 删除todo
    deleteTodo=(id)=>{
        //获取状态中的todos
        const {todos} = this.state;
        //删除指定id的todo
        const newTodos = todos.filter((todoObj)=>{
            return todoObj.id!==id
        })
        this.setState({todos:newTodos})
    }
    //用于全选或者全不选
    checkAllTodo = (done)=>{
        //获取原来的Todos
        const {todos} = this.state
        //加工数据
        const newTodos = todos.map((todoObj)=>{
            return {...todoObj,done}
        })
        //更新状态
        this.setState({todos:newTodos})
    }
    //清除已完成的todo
    handleClearAll=()=>{
        const {todos} = this.state;
        const newTodos = todos.filter((todoObj)=>{
            return !todoObj.done
        })
        this.setState({todos:newTodos})
    }
    render() {
        const {todos} = this.state;
        return (
            <div className="todo-container">
                <div className="todo-wrap">
                    <Header addTodo={this.addTodo}></Header>
                    <List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}></List>
                    <Footer handleClearAll={this.handleClearAll} checkAllTodo={this.checkAllTodo} todos={todos}></Footer>
                </div>
            </div>
        )
    }
}

3、App.css

/*base*/
body {
    background: #fff;
}

.btn {
    display: inline-block;
    padding: 4px 12px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
    border-radius: 4px;
}

.btn-danger {
    color: #fff;
    background-color: #da4f49;
    border: 1px solid #bd362f;
}

.btn-danger:hover {
    color: #fff;
    background-color: #bd362f;
}

.btn:focus {
    outline: none;
}

.todo-container {
    width: 600px;
    margin: 0 auto;
}
.todo-container .todo-wrap {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
}

4、Foot组件
4.1、index.jsx

//创建“外壳”组件APP
import React, {Component} from "react";
//引入样式
import "./index.css";
//创建并暴露App组件
export default class Footer extends Component {
    //全选
    checkAllTodo = (e)=>{
        this.props.checkAllTodo(e.target.checked);
    }
    handleClearAll = ()=>{
        this.props.handleClearAll();
    }
    render() {
        const {todos} = this.props;
        //获取已完成的任务数量
        const completedCount = todos.reduce((preValue,todo)=>{
            return preValue + (todo.done ? 1 : 0)
        },0)
        //总数
        const totalCount = todos.length;
        return (
            <div className="todo-footer">
                <label>
                    <input onChange={this.checkAllTodo} type="checkbox" checked={completedCount === totalCount && totalCount !== 0}/>
                </label>
                <span>
                    <span>已完成{completedCount}</span> / 全部{totalCount}
                </span>
                <button onClick={this.handleClearAll} className="btn btn-danger">清除已完成任务</button>
            </div>
        )
    }
}

4.2、index.css

/*footer*/
.todo-footer {
    height: 40px;
    line-height: 40px;
    padding-left: 6px;
    margin-top: 5px;
}

.todo-footer label {
    display: inline-block;
    margin-right: 20px;
    cursor: pointer;
}

.todo-footer label input {
    position: relative;
    top: -1px;
    vertical-align: middle;
    margin-right: 5px;
}

.todo-footer button {
    float: right;
    margin-top: 5px;
}

5、Header组件
5.1、index.jsx

//创建“外壳”组件APP
import React,{Component} from "react";
import PropTypes  from "prop-types";
//引入naono
import {nanoid} from "nanoid";
//引入样式
import "./index.css"
export default class Header extends Component{
    //对接收的props进行类型检查
    static propTypes = {
        addTodo:PropTypes.func.isRequired
    }
    addItem=(e)=>{
        //结构赋值
        const {keyCode,target} = e
        //判断是否是回车键
        if (keyCode!==13)return
        if(target.value.trim()===''){
            alert('输入不能为空')
            return;
        }
        //准备好一个新的todo对象
        const todoObj = {
            id:nanoid(),
            name:target.value,
            done:false
        }
        this.props.addTodo(todoObj)
        target.value=''
    }
    render(){
        return(
            <div className="todo-header">
                <input onKeyUp={this.addItem} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
            </div>
        )
    }
}

5.2、index.css

/*header*/
.todo-header input {
    width: 560px;
    height: 28px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 4px 7px;
}

.todo-header input:focus {
    outline: none;
    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}

6、Item组件
6.1、index.jsx

//创建“外壳”组件APP
import React,{Component} from "react";
//引入样式
import "./index.css";
export default class Item extends Component{
    state={
        mouse:false
    }
    handleMouse=(flag)=>{
        return ()=>{
            this.setState({
                mouse:flag
            })
        }
    }
    handleCheck=(id)=>{
        return (e)=>{
            this.props.updateTodo(id,e.target.checked)
        }
    }

    handleDelete=(id)=>{
        if(window.confirm('是否删除')){
            this.props.deleteTodo(id)
        }
    }
    render(){
        const {id,name,done} = this.props
        const {mouse} = this.state
        return(
            <li style={{backgroundColor:mouse?'#ddd':''}} onMouseLeave={this.handleMouse(false)} onMouseEnter={this.handleMouse(true)}>
                <label>
                    <input type="checkbox" checked={done} onChange={this.handleCheck(id)}/>
                    <span>{name}</span>
                </label>
                <button onClick={()=>{this.handleDelete(id)}} className="btn btn-danger" style={{display:mouse?'block':'none'}}>删除</button>
            </li>
        )
    }
}

6.2、index.css

/*item*/
li {
    list-style: none;
    height: 36px;
    line-height: 36px;
    padding: 0 5px;
    border-bottom: 1px solid #ddd;
}

li label {
    float: left;
    cursor: pointer;
}

li label li input {
    vertical-align: middle;
    margin-right: 6px;
    position: relative;
    top: -1px;
}

li button {
    float: right;
    display: none;
    margin-top: 3px;
}

li:before {
    content: initial;
}

li:last-child {
    border-bottom: none;
}

7、List组件
7.1、index.jsx

//创建“外壳”组件APP
import React,{Component} from "react";
import PropTypes from "prop-types";
//引入Item组件
import Item from "../Item";
//引入样式
import './index.css'
export default class List extends Component{
    static propTypes = {
        todos:PropTypes.array.isRequired,
        updateTodo:PropTypes.func.isRequired
    }
    render(){
        const {todos,updateTodo,deleteTodo} = this.props;
        return(
            <ul className="todo-main">
                {
                    todos.map((item,index)=>{
                        return <Item key={item.id} {...item} updateTodo={updateTodo} deleteTodo={deleteTodo}></Item>
                    })
                }
            </ul>
        )
    }
}

7.2、index.css

/*main*/
.todo-main {
    margin-left: 0px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0px;
}

.todo-empty {
    height: 40px;
    line-height: 40px;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding-left: 5px;
    margin-top: 10px;
}

8、实现效果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[极客大挑战 2020]Roamphp2-Myblog

又来喽 经过一番测试&#xff0c;发现文件包含&#xff0c;使用伪协议读取文件 例&#xff1a;php://filter/readconvert.base64-encode/resourcelogin //这里我只写php部分 //login.php <?php require_once("secret.php"); mt_srand($secret_seed); $_SESSION…

Kubernetes之Controller详解

本文尝试从Kubernetes Controller的种类、交互逻辑、最佳实践、伪代码示例及历史演进5个方面对其进行详细阐述&#xff0c;希望对您有所帮助&#xff01; 一、Kubernetes Controller种类 Kubernetes Controller Manager 是 Kubernetes 集群的核心组件之一&#xff0c;负责管理…

分布式系统:常见的陷阱和复杂性

分布式系统的复杂性是工程师和开发人员面临的重要挑战。复杂性往往会随着系统的发展而增加&#xff0c;因此积极主动非常重要。让我们来谈谈您可能会遇到哪些类型的复杂性以及在工作中应对它的有效策略。 分布式系统和复杂性 在开发中&#xff0c;分布式系统是相互连接并执行…

nacos 简述 安装运行

一、下载 官网:Redirecting to: https://nacos.io/ 文档:Nacos 快速开始 github地址:GitHub - alibaba/nacos: an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications. 下载nacos server(tips:也…

CVPR2024|vivo提出使用对抗微调获得泛化性更强的SAM,分割性能直接登顶 SOTA!

在计算机视觉不断发展的领域中&#xff0c;基础模型已成为一种关键工具&#xff0c;显示出对多种任务的出色适应性。其中&#xff0c;由 Meta AI 开发的 Segment Anything Model&#xff08;SAM&#xff09;在图像分割任务中表现杰出。然而&#xff0c;和其他类似模型一样&…

docker环境安装redis

docker下载redis镜像 docker pull redis:bullseye查看redis镜像 docker images创建redis容器 docker run \ -d \ --name redis \ -p 6379:6379 \ --restart unless-stopped \ -v /mydata/redis/data:/data \ -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \ redi…

【Leetcode】520. 检测大写字母

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517;我们定义&#xff0c;在以下情况时&#xff0c;单词的大写用法是正确的&#xff1a; 全部字母都是大写&#xff0c;比如 “USA” 。单词中所有字母都不是大写&#xff0c;比如 “le…

【前端项目笔记】4 权限管理

权限管理 效果展示&#xff1a; &#xff08;1&#xff09;权限列表 &#xff08;2&#xff09;角色列表 其中的分配权限功能 权限列表功能开发 新功能模块&#xff0c;需要创建新分支 git branch 查看所有分支&#xff08;*表示当前分支&#xff09; git checkout -b ri…

机器学习辅助的乙醇浓度检测(毕设节选)

目录 1.为什么要机器学习 2. 神经网络一般组成 3.BP神经网络工作过程 4.评价指标 5.实操代码 1.为什么要用机器学习 人工分析大量的谐振模式&#xff0c;建立各种WGM的响应与未知目标之间的关系&#xff0c;是一个很大的挑战。机器学习(ML)能够自行识别全谱的全部特征。作为…

021.合并两个有序链表,递归和遍历

题意 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 难度 简单 标签 链表、排序 示例 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[]…

Maven列出所有的依赖树

在 IntelliJ IDEA 中&#xff0c;你可以使用 Maven 插件来列出项目的依赖树。Maven 插件提供了一个名为dependency:tree的目标&#xff0c;可以帮助你获取项目的依赖树详细信息。 要列出项目的依赖树&#xff0c;可以执行以下步骤&#xff1a; 打开 IntelliJ IDEA&#xff0c;…

未来科技中的RTK接收机应用探索

RTK实时差分定位技术&#xff08;RTK&#xff0c;Real-Time Kinematic&#xff09;&#xff0c;作为高精度定位技术的一种重要手段&#xff0c;已经在地理测绘、测量工程、航空航天等领域取得了广泛应用。随着科技的不断发展&#xff0c;RTK导航接收机的应用领域也日益拓宽。首…

文华wh6均线交易策略多空波段止盈止损提示主图指标公式源码

文华wh6均线交易策略多空波段止盈止损提示主图指标公式源码&#xff1a; EMA120:EMA(C,120); RSV:(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100; K:SMA(RSV,3,1); D:SMA(K,3,1); J:3*K-2*D; DRAWTEXT(C>EMA120&&J<0,L,多),VALIGN0; DRAWTEXT(C<EMA…

Blazor的SSR服务端渲染是不是交互式的

从.NET8开始&#xff0c;Blazor引入了SSR服务端渲染&#xff0c;归功于MVC和RazePage的沉淀&#xff0c;虽然来得晚&#xff0c;但一经发布&#xff0c;就将Blazor推向了新的高度。从今年开始&#xff0c;Youtube上关于Blazor的优质教学视频&#xff0c;以肉眼可见的速度在增加…

基于Java的门禁系统【附源码】

第1章 绪论 1.1 课题背景 门禁系统就是对出入口通道进行管制的系统&#xff0c;它是在传统的门锁基础上发展而来的。传统的机械门锁仅仅是单纯的机械装置&#xff0c;无论结构设计多么合理&#xff0c;材料多么坚固&#xff0c;人们总能通过各种手段把它打开。在出入人员很多的…

写程序100道41-50

41.定义一个Father和Child类&#xff0c;并进行测试。 要求如下&#xff1a; (1)Father类为外部类&#xff0c;类中定义一个私有的String类型的属性name&#xff0c;name的值为“Join”。 (2)Child类为Father类的内部类&#xff0c;其中定义一个readName()方法&#xff0c;方…

PHP 界的扛把子 Swoole 异步通信利器

大家好&#xff0c;我是码农先森。 引言 我今天主要介绍的内容是包括但不仅限于 Swoole &#xff0c;也有一部分 Go 语言的内容。 为什么要介绍 Swoole ? 先说一说背景吧&#xff0c;我们项目组之前要为《香港 01》开发一个积分系统的项目&#xff0c;这个系统的主要功能包…

LINUX centos 安装jenkins超超超超超超级详细步骤

Jenkins安装 配置jdkmavengit jenkins 拉取 配置 jdk 1.安装jdk8 yum install java-1.8.0-openjdk-devel2.检查版本 java -version出现如下图查看版本信息 3. 设置JAVA_HOME环境变量 vim /etc/profile最下方输入 export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk expor…

鸿蒙开发HarmonyOS NEXT(一)

最近总听见大家讨论鸿蒙&#xff0c;前端转型的好方向&#xff1f;先入门学习下 目前官方版本和文档持续更新中 一、开发环境 提示&#xff1a;要占用的空间比较多&#xff0c;建议安装在剩余空间多的盘 1、下载&#xff1a;官网最新工具 - 下载中心 - 华为开发者联盟 (huaw…

记一次 APK 逆向动静调试 + so 动态链接库分析

0x00 前言&#xff1a; 好久没有做过安卓逆向了&#xff0c;最近重新系统地学习了安卓逆向技术。找到了一道较为典型的逆向分析题来练手&#xff0c;以锻炼动静态分析和动态链接库分析的基本能力。在这里记录基本的分析流程手法。 0x01 逆向分析&#xff1a; 一、使用 Genym…