1.Tolist案例(父子传参实现增删改)

目录结构

实现效果:

App.jsx

class App extends Component {
// 状态在哪里, 操作状态的方法就在哪里
state = {
todos:[
{id:1, name:'吃饭', done: true},
{id:2, name:'睡觉', done: true},
{id:3, name:'打代码', done: false},
{id:4, name:'光街', done: true},
]
} // addTodo用于添加一个todo, 接收的参数是todo对象
addTodo = (todoObj) =>{
const {todos} = this.state
const newTodos = [todoObj, ...todos]
this.setState({todos:newTodos})
} // updateTodo用于更新一个todo对象
updateTodo = (id, done) => {
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) => {
const {todos} = this.state
const newTodos = todos.filter((todoObj)=>{
// 将id不是要删除的todo,重新过滤到一个新数组
return todoObj.id !== id
})
this.setState({
todos:newTodos
})
}
//checkAllTodo用于全选或者取消全选
checkAllTodo = (done) => {
const {todos} = this.state
const newTodos = todos.map((todoObj)=>{
return {...todoObj, done}
})
this.setState({
todos:newTodos
})
} // 删除已完成的任务(done为true,删除已选中的,批量删除)
clearAllDone = () => {
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">
{/* 子传父 通过子调用父函数 传参 */}
<Headers addTodo={this.addTodo}/>
{/* 父传子 传参 */}
<List todos={todos} updateTodo={this.updateTodo} deleteTodo={this.deleteTodo}/>
<Footer todos={todos} checkAllTodo={this.checkAllTodo} clearAllDone={this.clearAllDone}/>
</div>
</div> )
}
}

Headers.jsx

class Headers extends Component{

    //对接收的props进行:类型、必要性的限制
static propTypes = {
addTodo:PropTypes.func.isRequired
} // 键盘回车事件, 13是回车返回的唯一值
handleKeyUp = (event) => {
const {keyCode, target} = event
if (keyCode !== 13 || target.value.trim() === '') return
const todoObj = {id:nanoid(), name:target.value, done:false}
// 调用父组件函数,添加一个todoObj
this.props.addTodo(todoObj)
// 清空输入框
target.value = ''
// console.log(event.target.value, event.keyCode) } render() {
return (
<div className="todo-header">
{/*监听键盘事件*/}
<input onKeyUp={this.handleKeyUp} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
</div>
)
}
}

List.jsx

class List extends Component{

    // 对接收的props进行类型、必要性限制
static propTypes = {
todos: PropTypes.array.isRequired,
updateTodo: PropTypes.func.isRequired,
deleteTodo: PropTypes.func.isRequired, } render() {
// 接收从父组件传来的数组和方法
const {todos, updateTodo, deleteTodo} = this.props
return (
<ul className="todo-main">
{
todos.map(todo => {
return <Items key={todo.id} {...todo} updateTodo={updateTodo} deleteTodo={deleteTodo}/>
})
} </ul>
)
}
}

Items.jsx

class Items extends Component {

    state = {mouse:false}  // 标识鼠标移入、移出

    //鼠标移入、移除的回调
handleMouse = (flag) =>{
// 函数柯里化
return () =>{
this.setState({mouse:flag})
}
} // 勾选、取消勾选某一个todo的回调
handleCheck = (id) => {
return (event)=>{
this.props.updateTodo(id, event.target.checked)
// console.log(id, event.target.checked)
} } // 删除一个todo的回调
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': 'white'}} onMouseEnter={this.handleMouse(true)} onMouseLeave={this.handleMouse(false)}>
<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>
)
}
}

Footer.jsx

class Footer extends Component{

    handleCheckAll = (event) => {
// 是否全选或者取消选中
const done = event.target.checked
this.props.checkAllTodo(done)
} render() {
const {todos} = this.props
// 已完成的个数
const doneCount = todos.reduce((pre, todo)=>pre+(todo.done? 1 : 0),0)
// 总数
const total = todos.length return (
<div className="todo-footer">
<label>
<input onChange={this.handleCheckAll} type="checkbox" checked={doneCount === total && total !== 0}/>
</label>
<span><span>已完成{doneCount}</span> / 全部{total}</span>
<button onClick={this.props.clearAllDone} className="btn btn-danger">清除已完成任务</button>
</div>
)
}
}

Tolist案例(父子传参实现增删改)的更多相关文章

  1. javascript之url转义escape()、encodeURI()和decodeURI(),ifram父子传参参数有中文时出现乱码

    ifram父子传参参数有中文时出现乱码,可先在父级页面用encodeURI转义,在到子页面用进行decodeURI()解码 我们可以知道:escape()除了 ASCII 字母.数字和特定的符号外,对 ...

  2. JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删改查),事件

    JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删 ...

  3. 微信小程序(14)--上传图片公用组件(父子传参)

    这周整理了一下做微信小程序页面时遇到的一些问题,先说说常见的上传图片吧. 上传图片公用组件 首先要了解的是父子传参. 1.A组件为父组件,B组件为子组件,以下是A组件向B组件传参: 在A组件的json ...

  4. node.js(小案例)_实现学生信息增删改

    一.前言 本节内容主要对小案例做一个总结: 1.如何开始搭建小项目 2.路由设计 3.模块应用 4.项目源码以及实现过程github地址: 项目演示如下: 二.主要内容 1.项目的关键性js源码: 项 ...

  5. Node教程——Node+MongoDB案例实现用户信息的增删改查

    想要获取源代码的同学可以留言,我不做git上传了,案例太简单 没必要 综合演练 用户信息的增删改查 需求:你需要实现这样的结果 点击添加可以添加用户,点击删除可以删除点击修改可以修改 代码分析: 1. ...

  6. Java Web项目案例之---登录注册和增删改查(jsp+servlet)

    登录注册和增删改查(jsp+servlet) (一)功能介绍 1.用户输入正确的密码进行登录 2.新用户可以进行注册 3.登录后显示学生的信息表 4.可以添加学生 5.可以修改学生已有信息 6.可以删 ...

  7. 页面嵌入iframe关于父子传参调用

    1.首先来说一下iframe是干什么用的 IFRAME是HTML标签,作用是文档中的文档,或者浮动的框架(FRAME).iframe元素会创建包含另外一个文档的内联框架(即行内框架),通俗点说就是在一 ...

  8. ssm框架(Spring Springmvc Mybatis框架)整合及案例增删改查

    三大框架介绍 ssm框架是由Spring springmvc和Mybatis共同组成的框架.Spring和Springmvc都是spring公司开发的,因此他们之间不需要整合.也可以说是无缝整合.my ...

  9. react中的传参方式

    react是一个SPA模式,即组件嵌套租,在一个单页面的应用中组件间的数值传递是必不可少的,主要的传参方式大致有一下几种: 1,在挂载的地方给组件传参 ReactDOM.rander(<a na ...

随机推荐

  1. java String转List<Device>集合

    // 从Redis中获得正常设备的数量 String success = redisService.get(RedisKey.CULTIVATION_RECORD_SUCCESS); //建立一个li ...

  2. element UI表格行高、padding等设置报错问题

    element UI里面表格的行高需要自己调整高度和设置padding,直接写style是不行的,里面有 : 1.row-style (行的 style) 2.header-row-styl   (表 ...

  3. MySQL中特别实用的几种SQL语句【转】

    一.插入或替换 如果我们想插入一条新记录(INSERT),但如果记录已经存在,就先删除原记录,再插入新记录. 情景示例:这张表存的每个客户最近一次交易订单信息,要求保证单个用户数据不重复录入,且执行效 ...

  4. python2 与 python3 依赖包冲突问题

    原文链接   https://www.2cto.com/database/201805/749294.html 执行pip的时候取的是/usr/bin这里的pip,查看这里是否存在pip3,没有的话需 ...

  5. 还不了解一下 Java 8 Predicate 函数接口

    同学你好,这里有一份你的未读代码,等你查收. 这篇文章属于 Java 8 教程(LTS)系列教程,点击阅读更多相关文章. Predicate 函数接口同之前介绍的 Function 接口一样,是一个函 ...

  6. Elsevier(爱思唯尔)期刊模板的使用

    1.爱思唯尔(Elsevier)期刊模板的使用 2.sci论文(以Elsevier为例) latex文件从小白到投稿 3.初次使用爱斯维尔(Elsevier)论文模板遇到的坑 4.latex学习 da ...

  7. Linux账号管理(入门)

    引言 对用户的操作要在root权限下执行 创建用户 useradd useradd -m username:创建一个用户名为:username的用户 -m参数代表自动创建这个用户的主目录 删除用户 u ...

  8. Python小白的数学建模课-12.非线性规划

    非线性规划是指目标函数或约束条件中包含非线性函数的规划问题,实际就是非线性最优化问题. 从线性规划到非线性规划,不仅是数学方法的差异,更是解决问题的思想方法的转变. 非线性规划问题没有统一的通用方法, ...

  9. IDEA使用Tomcat时控制台乱码的解决方案>从零开始学JAVA系列

    IDEA使用Tomcat时控制台乱码的解决方案 解决方案1,修改启动时虚拟机参数 解决方案2,修改idea的设置 解决方案3,修改idea配置文件 在最后添加一行 '-Dfile.encoding=U ...

  10. Windows协议 LDAP篇 - 域权限

    windows 访问控制模型 也就是大名鼎鼎的ACM,access control mode 由两部分组成的. 访问令牌(access tokens) 其中包含有关登录用户的信息(User SID,G ...