react+typescript 实现简单的任务列表

react+typescript / 1377人浏览 / 0人评论

react+typescript 实现简单的任务列表

包含添加,删除,完成,删除已完成,全选等功能

App.tsx

import React from 'react';
import './App.css';
import Header from "./components/Header/Header";
import Task from "./components/Task/Task";
import Footer from "./components/Footer/Footer";

type dataType = { id: number, title: string, fished: boolean }
type stateType = {
 list: dataType[],
 total: number,
 fishedtotal: number
};

class App extends React.Component<any, stateType> {
 constructor(props: any) {
   super(props);
   this.state = {
     list: [{
       id: 1,
       title: "任务1",
       fished: false,
     }, {
       id: 2,
       title: "任务2",
       fished: false,
     }, {
       id: 3,
       title: "任务3",
       fished: false,
     }, {
       id: 4,
       title: "任务4",
       fished: false,
     },],
     total: 0,
     fishedtotal: 0,
   }
 }
 componentDidMount() {
   let list = this.state.list;
   let count = 0;
   let total = this.state.list.length;
   list.forEach((item,index)=>{
     if(item.fished === true){
       count++
     }
   })
   this.setState({
     fishedtotal: count,
     total: total
   })
 }

 addMsg = (data: dataType): void => {
   let list = this.state.list;
   list.push(data);
   this.setState({
     list,
     total: list.length
   })
 }
 del = (id: number): void => {
   let list = this.state.list;
   let fishedtotal = this.state.fishedtotal;
   list.forEach((item,index)=>{
     if(item.id === id){
       list.splice(index, 1);
       if(item.fished === true){
         fishedtotal--;
       }
     }
   })

   this.setState({
     list,
     total: list.length,
     fishedtotal
   })
 }
 delfinesh = (): void => {
   let list = this.state.list;
   let temparr:Array<dataType> = [];
   list.forEach((item)=>{
     if(item.fished === false){
       temparr.push(item)
     }
   })
   this.setState({
     list:temparr,
     total: temparr.length,
     fishedtotal: 0
   })

 }
 changeFished=(fished:boolean,id:number)=>{
   let list = this.state.list;
   let fishedtotal = this.state.fishedtotal;
   list.forEach((item,index)=>{
     if(item.id === id){
       list[index].fished = fished;
       if(item.fished === true){
         fishedtotal++;
       }else{
         fishedtotal--;
       }
     }
   })
   this.setState({
     list,
     fishedtotal
   })
 }
 checkAll=(ck:boolean)=>{

   let list = this.state.list;
   let fishedtotal = 0;
   if(ck){
     fishedtotal = list.length;
   }else{
     fishedtotal = 0;
   }
   list.forEach((item,index)=>{
     if(ck){
       list[index].fished = true;
     }else{
       list[index].fished = false;
     }
   })
   this.setState({
     list,
     fishedtotal
   })
 }
 render() {
   const {list} = this.state;
   const lastItem = list[list.length-1];
   return (
     <>
       <div className="taskView">
         <Header addmsg = {this.addMsg}  lastId={lastItem ? lastItem.id : 0 }></Header>
         <Task list = {this.state.list}  changeFished={this.changeFished}  del={this.del}></Task>
         <Footer delfinesh={this.delfinesh} checkAll={this.checkAll} total={this.state.total} fishedtotal={this.state.fishedtotal}></Footer>
       </div>
     </>
   );
 }

}

export default App;


Header.tsx

import React, {Component} from 'react';
type dataType = { id: number, title: string, fished: boolean }
type protype = {
 addmsg: (data:dataType)=>void,
 lastId: number
}

type stateType = {

}

class Header extends Component<protype,stateType> {
 constructor(props:protype) {
   super(props);
 }

 render() {
   const {addmsg, lastId} = this.props;
   return <>
     <div className="Header"> <input type="text" onKeyDown={(ev)=>{

       if(ev.keyCode === 13){
         addmsg({
           id: lastId+1,
           title: ev.currentTarget.value,
           fished: false
         })
       }

     }} /></div>
   </>;
 }
}

export default Header;

Task.tsx

import React, {Component} from 'react';
import ListItem from "../ListItem/ListItem";
import {finished} from "stream";
type protype = {
 list: { id: number, title: string, fished: boolean }[],
 del: (id:number)=>void,
 changeFished: (fished: boolean, index:number)=>void
}

type stateType = {

}

class Task extends Component<protype,stateType> {
 constructor(props:protype) {
   super(props);
 }

 render() {
   const {list,del} = this.props;
   const relist = list.sort().reverse();
   return <>
     <ul className={"taskul"}>
       {
         relist.map((item,index)=>(<ListItem
           changeFished = {this.props.changeFished}
           data={item}
           del={del}
           id={item.id}
           key={item.id}
         ></ListItem>))
       }
     </ul>
   </>;
 }
}

export default Task;


ListItem.tsx

import React, {Component} from 'react';

type protype = {
 data: { id: number, title: string, fished: boolean },
 del: (index:number)=>void,
 id: number,
 changeFished: (fished: boolean, index:number)=>void
}

type stateType = {
 hover: boolean,
}

class ListItem extends Component<protype,stateType> {
 constructor(props:protype) {
   super(props);
   this.state = {
     hover: false,
   }
 }

 render() {
   const {data,del,id,changeFished} = this.props;
   const {hover} = this.state;
   return <>
     <li
       className={data.fished ? 'itemli cur' : 'itemli'}
       onMouseOver={()=>{
         this.setState({
           hover: true
         })
       }}
       onMouseOut={()=>{
         this.setState({
           hover: false
         })
       }}

     >
       <label className={"label"}>
         <input
           type="checkbox"
           onChange={(ev)=>{
             let ck = !data.fished;
             changeFished(ck,id);
           }}
           checked={data.fished ? true : false}
         />

         <p className={"tasktitle"}>{data.title}</p>
       </label>
       <button onClick={()=>del(id)} style={{display: hover ? 'block': 'none'}}>删除</button>
     </li>
   </>;
 }
}


export default ListItem;

Footer.tsx

import React, {Component} from 'react';

type protype = {
 delfinesh: () => void,
 fishedtotal: number,
 total: number,
 checkAll: (ck: boolean) => void
}

type stateType = {

}

class Footer extends Component<protype, stateType> {
 constructor(props: protype) {
   super(props);
 }

 render() {
   const {fishedtotal, total, checkAll} = this.props;
   return <>

     <div className="Footer">
       <label>
         <input type="checkbox"
                checked={fishedtotal === total}
                onChange={(ev) => {
                  let ck = !(fishedtotal === total);
                  checkAll(ck)
                }}
         />
       </label>
       <div className="total">
         共计{total}条/已完成{fishedtotal}
       </div>
       <button onClick={() => {
         this.props.delfinesh()
       }}>删除已完成
       </button>
     </div>

   </>;
 }
}

export default Footer;


效果截图

image.png


好好学习,天天向上!

0 条评论

还没有人发表评论

发表评论 取消回复

记住我的信息,方便下次评论
有人回复时邮件通知我