React脚手架——TodoList案例

React脚手架简介

快速构建模块化、组件化、工程化项目

创建项目步骤

1.npm i create-react-app -g
2.create-react-app react-demo
3.cd react-demo
4.npm start

在这里插入图片描述

TodoList案例

效果图
在这里插入图片描述
代码目录
在这里插入图片描述

App组件

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

export default class App extends Component {
    
    

	state = {
    
    todos:[
		{
    
    id:'1',name:'刷B站',done:true},
		{
    
    id:'2',name:'刷csdn',done:false},
		{
    
    id:'3',name:'刷小红书',done:false},
	]}

	//添加todo
	addTodo = (todoObj)=>{
    
    
		const {
    
    todos} = this.state
		const newTodos = [todoObj,...todos]
		this.setState({
    
    todos:newTodos})
	}

	//更新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})
	}

	//删除todo
	deleteTodo = (id)=>{
    
    
		const {
    
    todos} = this.state
		const newTodos = todos.filter((todoObj)=>{
    
    
			return todoObj.id !== id
		})
		this.setState({
    
    todos:newTodos})
	}

	//全选todo
	checkAllTodo = (done)=>{
    
    
		const {
    
    todos} = this.state
		const newTodos = todos.map((todoObj)=>{
    
    
			return {
    
    ...todoObj,done}
		})
		this.setState({
    
    todos:newTodos})
	}

	//清除已办
	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">
					<Header addTodo={
    
    this.addTodo}/>
					<List todos={
    
    todos} updateTodo={
    
    this.updateTodo} deleteTodo={
    
    this.deleteTodo}/>
					<Footer todos={
    
    todos} checkAllTodo={
    
    this.checkAllTodo} clearAllDone={
    
    this.clearAllDone}/>
				</div>
			</div>
		)
	}
}

Header组件

import React, {
    
     Component } from 'react'
import PropTypes from 'prop-types'
import {
    
    nanoid} from 'nanoid'
import './index.css'

export default class Header extends Component {
    
    

	static propTypes = {
    
    
		addTodo:PropTypes.func.isRequired
	}

	//回车添加代办
	handleKeyUp = (event)=>{
    
    
		const {
    
    keyCode,target} = event
		if(keyCode !== 13) return
		if(target.value.trim() === ''){
    
    
			alert('输入不能为空')
			return
		}
		const todoObj = {
    
    id:nanoid(),name:target.value,done:false}
		this.props.addTodo(todoObj)
		target.value = ''
	}

	render() {
    
    
		return (
			<div className="todo-header">
				<input onKeyUp={
    
    this.handleKeyUp} type="text" placeholder="请输入待办"/>
			</div>
		)
	}
}

List组件

import React, {
    
     Component } from 'react'
import PropTypes from 'prop-types'
import Item from '../Item'
import './index.css'

export default class List extends Component {
    
    

	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 <Item key={
    
    todo.id} {
    
    ...todo} updateTodo={
    
    updateTodo} deleteTodo={
    
    deleteTodo}/>
					})
				}
			</ul>
		)
	}
}

Iitem组件

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 (event)=>{
    
    
			this.props.updateTodo(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组件

import React, {
    
     Component } from 'react'
import './index.css'

export default class Footer extends Component {
    
    

	//全选
	handleCheckAll = (event)=>{
    
    
		this.props.checkAllTodo(event.target.checked)
	}

	//清除已办
	handleClearAllDone = ()=>{
    
    
		this.props.clearAllDone()
	}

	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 type="checkbox" onChange={
    
    this.handleCheckAll} checked={
    
    doneCount === total && total !== 0 ? true : false}/>
				</label>
				<span>
					<span>已完成{
    
    doneCount}</span> / 全部{
    
    total}
				</span>
				<button onClick={
    
    this.handleClearAllDone} className="btn btn-danger">清除已完成任务</button>
			</div>
		)
	}
}

猜你喜欢

转载自blog.csdn.net/qq_33591873/article/details/128294575