第十九章 案例TodoList之组件拆分

news2024/11/26 20:27:36

光说不练假把式,接下来我们将练习一个案例TodoList,让我们熟悉react。

在这里插入图片描述


以上是该案例的静态示例,其功能有:

  • 在输入框输入任务,按回车键新增一个任务项
  • 鼠标移动在单个任务项上面,出现删除按钮
  • 点击删除按钮,可以将当前任务项删除
  • 选中任务项,点击清除已完成任务项,可以将已选中的任务项全部删除
  • 底部实时显示已选中的任务项的数量和全部任务项的数量

静态页面拆分组件

我们可以根据静态页面,根据自己的理解来进行功能组件的拆分。我们在来回顾一下组件的概念:

组件是一种可重用的代码块,它可以被多次使用,而不需要重复编写相同的代码。组件可以是一个函数、一个类或一个模块,它们可以接受输入参数并返回输出结果。

在前端开发中,组件通常指的是 UI 组件,它们是构建用户界面的基本单元。UI 组件可以是按钮、文本框、下拉菜单等等,它们可以被组合在一起形成复杂的用户界面。

在这里插入图片描述


从上图我们可以知道,我们将静态页面拆分成了5个组件:

  • APP组件,是一个容器,其他组件都将引入到这个容器里面
  • header组件,用来添加任务项
  • Item组件,用来展示单个任务项
  • List组件,是一个Item的父组件,可以展示多个任务项
  • footer组件,用来展示已完成和全部的任务项数量,以及删除已完成任务项的功能

使用脚手架展示整体静态页面

我们可以将整体的页面全部写在APP组件里面,然后我们在分析

  • index.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;
}

/*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);
}

/*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;
}
/*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;
}

/*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;
}

  • App.jsx
import React, { Component } from 'react'

import "./index.css"

export default class App extends Component {
  render() {
    return (
      <div className="todo-container">
      <div className="todo-wrap">
        <div className="todo-header">
          <input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
        </div>
        <ul className="todo-main">
          <li style={{backgroundColor: 'gainsboro'}}>
            <label>
              <input type="checkbox"/>
              <span>xxxxx</span>
            </label>
            <button className="btn btn-danger" style={{display:"block"}}>删除</button>
          </li>
          <li>
            <label>
              <input type="checkbox"/>
              <span>yyyy</span>
            </label>
            <button className="btn btn-danger" style={{display:"none"}}>删除</button>
          </li>
        </ul>
        <div className="todo-footer">
          <label>
            <input type="checkbox"/>
          </label>
          <span>
            <span>已完成0</span> / 全部2
          </span>
          <button className="btn btn-danger">清除已完成任务</button>
        </div>
      </div>
    </div>
    )
  }
}

  • 查看效果

在这里插入图片描述

从图可知我们已经将页面显示成功了,需要注意的是:

  • 类名class需要写成className
  • 内联样式style的写法style={{color:'red'}}

拆分组件并编写代码

  • 首先我们先将组件的文件目录建好
components
|----Header
		|----index.css
		|----index.jsx
|----List
		|----index.css
		|----index.jsx
|----Item
		|----index.css
		|----index.jsx
|----Footer
		|----index.css
		|----index.jsx
  • 编写Header组件

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);
}

index.jsx

import React, { Component } from 'react'
import "./index.css"
export default class Header extends Component {
  render() {
    return (
      <div className="todo-header">
          <input type="text" placeholder="请输入你的任务名称,按回车键确认"/>
      </div>
    )
  }
}
  • 编写Item组件

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;
}

index.jsx

import React, { Component } from 'react'
import "./index.css"
export default class Item extends Component {
  render() {
    return (
      <li style={{backgroundColor: 'gainsboro'}}>
            <label>
              <input type="checkbox"/>
              <span>xxxxx</span>
            </label>
            <button className="btn btn-danger" style={{display:"block"}}>删除</button>
      </li>
    )
  }
}

  • 编写List组件

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;
}

index.jsx

import React, { Component } from 'react'
import Item from '../Item'
import "./index.css"
export default class List extends Component {
  render() {
    return (
      <ul className="todo-main">
          <Item/>
      </ul>
    )
  }
}

注意:因为List组件是Item的父组件,所以这里需要将Item组件引入使用

  • 编写Footer组件

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;
}

index.jsx

import React, { Component } from 'react'
import "./index.css"
export default class Footer extends Component {
  render() {
    return (
      <div className="todo-footer">
      <label>
        <input type="checkbox"/>
      </label>
      <span>
        <span>已完成0</span> / 全部2
      </span>
      <button className="btn btn-danger">清除已完成任务</button>
    </div>
    )
  }
}
  • 编写APP组件

index.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;
}

App.jsx

import React, { Component } from 'react'
import Header from "./components/Header"
import List from "./components/List"
import Footer from "./components/Footer"
import "./index.css"

export default class App extends Component {
  render() {
    return (
      <div className="todo-container">
      <div className="todo-wrap">
        <Header/>
        <List/>
        <Footer/>
      </div>
    </div>
    )
  }
}
  • 最后运行看看效果

在这里插入图片描述

我们可以看到页面以及成功出现了,我们需要效果,说明我们静态拆分成功。


总结

  • 根据整体页面,思考如何拆分界面,如何抽取组件,可以画图理解。
  • 拆分组件时,先将静态的效果一个一个拆分为组件,组合起来不报错,在进行下一步。

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

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

相关文章

密度聚类算法(DBSCAN)实验案例

密度聚类算法&#xff08;DBSCAN&#xff09;实验案例 描述 DBSCAN是一种强大的基于密度的聚类算法&#xff0c;从直观效果上看&#xff0c;DBSCAN算法可以找到样本点的全部密集区域&#xff0c;并把这些密集区域当做一个一个的聚类簇。DBSCAN的一个巨大优势是可以对任意形状…

SpringSecurity 学习笔记 下(微服务权限方案)

SpringSecurity 微服务权限方案 一、 什么是微服务 1.1 微服务由来 微服务最早由 Martin Fowler 与 James Lewis 于 2014 年共同提出&#xff0c;微服务架构风格是一种使用一套小服务来开发单个应用的方式途径&#xff0c;每个服务运行在自己的进程中&#xff0c;并使用轻量级…

使用Swagger生成在线文档

目录 1&#xff1a;Swagger介绍 2&#xff1a;使用 2.1&#xff1a;swaager集成boot依赖 2.2&#xff1a;配置文件中配置相关信息 2.3&#xff1a;在启动类中加入相关注解 2.4&#xff1a;测试 3&#xff1a;swagger常用注解 1&#xff1a;Swagger介绍 在前后端分离开发…

GET和POST方式请求API接口数据返回

区别&#xff1a; GET在浏览器回退时是无害的&#xff0c;而POST会再次提交请求。 GET产生的URL地址可以被Bookmark&#xff0c;而POST不可以。 GET请求会被浏览器主动cache&#xff0c;而POST不会&#xff0c;除非手动设置。 GET请求只能进行url编码&#xff0c;而POST支持…

DETR【论文阅读】

End-to-End Object Detection with Transformers 1. Introduction 发表&#xff1a;ECCV 2020影响&#xff1a;在目标检测上使用了一种全新的架构&#xff0c;是里程碑式的工作。简单优雅统一的结构&#xff0c;不再依赖于人的先验知识&#xff08;anchor生成&#xff0c;nms…

二叉树_详解

目录 1. 树型结构 1.1 概念 1.2 概念 1.3 树的表示形式 1.4 树的应用 2. 二叉树 2.1 概念 2.2 两种特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 二叉树的基本操作 2.5.1 前置说明 2.5.2 二叉树的遍历 2.5.3 二叉树的基本操作 1. 树型结构 1.1 概念 …

k8s集群上安装Velero,用Velero备份K8S的数据

前提条件&#xff1a; 需要有一个K8S集群&#xff01; 一、概述 Velero是一个开源工具&#xff0c;可以安全地备份和还原&#xff0c;执行灾难恢复以及迁移Kubernetes集群资源和持久卷。 二、docker安装minio mkdir -p /home/minio docker run -p 9000:9000 -p 9090:9090 …

Win11去掉桌面图标快捷方式(2)----Dism++

1.Dism介绍 Dism&#xff0c;也许是最强的实用工具全球第一款基于 CBS 的 Dism GUI 实现。 兼容 Windows Vista/7/8/8.1/10 Dism可以说是一个Dism的GUI版&#xff0c;但是并不依赖Dism&#xff0c;直接基于更底层的CBS&#xff08;Component Based Servicing Reference&…

第1章 如何听起来像数据科学家

第1章 如何听起来像数据科学家 文章目录第1章 如何听起来像数据科学家1.1.1 基本的专业术语1.1.3 案例&#xff1a;西格玛公司1.2.3 为什么是Python1.4.2 案例&#xff1a;市场营销费用1.4.3 案例&#xff1a;数据科学家的岗位描述我们拥有如此多的数据&#xff0c;而且正在生产…

山西省税务汇总申报流程

1、国家税务总局山西省电子税务局 企业登录&#xff1a;填写社会信用代码、密码、手机号、获取验证码&#xff0c;即可登录成功。 2、登录成功后&#xff0c;按下图 第一步进行数据更新、第二步点击“我要办税”->税费申报及缴纳 3、先填写报表->增值税及附加税 4、…

每日学术速递4.11

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.InstantBooth: Personalized Text-to-Image Generation without Test-Time Finetuning 标题&#xff1a;InstantBooth&#xff1a;无需测试时间微调的个性化文本到图像生成 作者&a…

九耶丨钛伦特-用深度学习实现垃圾图像分类(一)

在这个项目中我们将结合我们的日常生活&#xff0c;让计算机帮助我们进行垃圾分类。比如让计算机能够正确将如下三张包含不同垃圾的图像进行分类。 我们希望计算机能够识别出三张图像依次是玻璃&#xff08;玻璃瓶&#xff09;&#xff0c;纸张&#xff08;信封&#xff09;和塑…

Kafka学习记录

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。希望互相进步谢谢&#xff01;&#xff01; 文章目录阅读前请看一下&#xff1a;我是一…

“商量”翻车了?网友质疑搬运C站

在ChatGPT大热的当下&#xff0c;各大互联网和AI大厂陆续开始推出国内版本的大模型产品了&#xff0c;最近发布的有&#xff1a;商汤版ChatGPT发布千亿参数大模型&#xff1a;商量&#xff01;第一个真正实现智能涌现的国产大语言模型&#xff0c;内测即将开启阿里版 ChatGPT 突…

ICLR 2023 | 基于视觉语言预训练模型的医疗图像小样本学习及零样本推理性能研究

近两年&#xff0c;视觉语言模型 (VLM) 逐渐兴起&#xff0c;并在小样本学习 (Few-shot Learning) 和零样本推理 (Zero-shot Inference) 上取得了令人注目的成果。那么这些在自然图像上取得成功的大规模预训练视觉语言模型&#xff0c;是否能成功应用到医疗领域呢&#xff1f;抱…

springboot项目中的mysql用国产数据库达梦替换的相关说明

一、 用“DM管理工具”的“管理用户”创建你需要用户&#xff0c;也是达梦的模式。 用户的权限问题可以直接角色授权&#xff0c;方便一些。 二、借用达梦的“DM数据迁移工具”做数据库的表内容转移。 1. 新建工程、新建迁移 编辑mysql的数据库源 编辑达梦的目的端数据库 选择之…

力扣119杨辉三角 II:代码实现 + 方法总结(数学规律法 记忆法/备忘录)

文章目录第一部分&#xff1a;题目第二部分&#xff1a;解法①-数学规律法2.1 规律分析2.2 代码实现2.3 需要思考第三部分&#xff1a;解法②-记忆法&#xff08;备忘录&#xff09;第四部分&#xff1a;对比总结第一部分&#xff1a;题目 &#x1f3e0; 链接&#xff1a;119.…

工业路由器IO远程控制使用说明(智联物联)

工业路由器IO控制是指路由系统已开发支持对用户DI&#xff08;数字输入&#xff09;/DO&#xff08;数字输出&#xff09;/Relay&#xff08;继电器&#xff09;类型的设备控制操作&#xff0c;目前各支持1路设备类型。 IO控制目前支持2种方式进行控制操作&#xff0c;即通过工…

C/C++每日一练(20230417)

目录 1. 字母异位词分组 &#x1f31f;&#x1f31f; 2. 计算右侧小于当前元素的个数 &#x1f31f;&#x1f31f;&#x1f31f; 3. 加一 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 J…

【JavaScript】3.JavaScript预解析

JavaScript 预解析 1. 变量预解析 和 函数预解析 js引擎运行js 分为两步&#xff1a; 预解析 代码执行 预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面代码执行 按照代码书写的顺序从上往下执行 预解析分为 变量预解析&#xff08;变量提升&…