耀极客论坛

 找回密码
 立即注册
查看: 624|回复: 0

react实现todolist的增删改查详解

[复制链接]

336

主题

318

帖子

22万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
220553
发表于 2022-5-9 00:19:57 | 显示全部楼层 |阅读模式
  这篇文章主要为大家介绍了react实现todolist的增删改查,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助


以todolist为例




目录如下


app.js
  1. import React, {  PureComponent } from 'react'
  2. import Input from './components/Input'
  3. import List from './components/List'
  4. import Total from './components/Total'
  5. import Mask from './components/Mask'
  6. import { bus as $bus } from './components/bus'
  7. import './App.css'
  8. export default class App extends PureComponent {
  9.   constructor() {
  10.     super()
  11.     this.state = {
  12.       flag: false,
  13.       list: [
  14.         {
  15.           id: 1,
  16.           content: '哈哈哈',
  17.           checked: false
  18.         },
  19.         {
  20.           id: 7,
  21.           content: '哈哈哈',
  22.           checked: false
  23.         },
  24.         {
  25.           id: 5,
  26.           content: '哈哈哈',
  27.           checked: false
  28.         },
  29.       ],
  30.       checkAll: false,
  31.       selectLength: 0,
  32.       item: {}
  33.     }
  34.   }
  35.   // 全选全不选
  36.   checkAllHandler(checked) {
  37.     console.log("checked",checked);
  38.     const { list } = this.state
  39.     const newList = list.map(item =>{
  40.       return {...item,checked}
  41.     })
  42.     this.setState({list:newList,checkAll: checked},()=>{
  43.       this.doneLenth()
  44.     })
  45.   }
  46.   // 单选单不选
  47.   checkHandler =(id,checked)=> {
  48.     const { list } = this.state
  49.     const newList = list.map(item => {
  50.       return item.id === id ? {...item,checked} : item
  51.     })
  52.     let checkAll = newList.length && newList.every(item => item.checked)
  53.     this.setState(() => ({list: newList,checkAll}),()=>{
  54.       this.doneLenth()
  55.     })
  56.   }
  57.   // 添加
  58.   addHandler = (obj)=>{
  59.     let { list } = this.state;
  60.     let newList = [...list,obj]
  61.     console.log('newList===='+newList)
  62.     this.setState({
  63.       list: newList,
  64.     },()=>{
  65.       this.doneLenth()
  66.     })
  67.   }
  68.   // 搜索
  69.   searchHandler=(content)=>{
  70.     console.log("content",content);
  71.     let { list } = this.state;
  72.     let newList = list.filter(item => item.content.includes(content))
  73.     this.setState({
  74.       list: newList
  75.     },()=>{
  76.       this.doneLenth()
  77.     })
  78.   }
  79.   // 删除
  80.   delHandler = (id)=> {
  81.     console.log("id",id);
  82.     const { list } = this.state
  83.     const newList = list.filter(item => item.id !=id)
  84.     let checkAll = newList.length && newList.every(item => item.checked)
  85.     this.setState(() => ({list: newList,checkAll}),()=>{
  86.       this.doneLenth()
  87.     })
  88.   }
  89.   // 编辑
  90.   editHandler = (items)=>{
  91.     this.setState({
  92.       item: items
  93.     })
  94.   }
  95.   // 更新
  96.   update = (content)=>{
  97.     const { list,item } = this.state
  98.     let obj = Object.assign(item,{content})
  99.     const newList = list.map(v =>{
  100.       if(v.id === obj.id) {
  101.         v = {...obj}
  102.       }
  103.       return v
  104.     })
  105.     this.setState({
  106.       list: newList,
  107.       item: obj
  108.     })
  109.   }
  110.   // 已完成
  111.   doneLenth=()=> {
  112.     const { list } = this.state
  113.     const newList = list.filter(item => item.checked)
  114.     let selectLength = newList.length
  115.     setTimeout(()=>{
  116.       this.setState({
  117.         selectLength
  118.       })
  119.     })
  120.   }
  121.   // 挂载
  122.   componentDidMount() {
  123.     this.unSubscribe = $bus.addListener("getFlag",(flag)=>{
  124.       this.setState({flag})
  125.     })
  126.     this.unSubscribe1 = $bus.addListener("sendValue",(obj)=>{
  127.      this.addHandler(obj)
  128.     })
  129.     this.unSubscribe2 = $bus.addListener("searchValue",(value)=>{
  130.      this.searchHandler(value)
  131.     })
  132.     this.unSubscribe3 = $bus.addListener("getItem",(item)=>{
  133.      this.editHandler(item)
  134.     })
  135.     this.unSubscribe4 = $bus.addListener("update",(content)=>{
  136.      this.update(content)
  137.     })
  138.   }
  139.   // 卸载
  140.   componentWillUnmount() {
  141.     $bus.removeListener(this.unSubscribe)
  142.     $bus.removeListener(this.unSubscribe1)
  143.     $bus.removeListener(this.unSubscribe2)
  144.     $bus.removeListener(this.unSubscribe3)
  145.     $bus.removeListener(this.unSubscribe4)
  146.   }
  147.   render() {
  148.     let { flag, list,checkAll,selectLength } = this.state
  149.     return (
  150.       ‹div className='container'>
  151.         {/* 输入框 */}
  152.         ‹Input>‹/Input>
  153.         {/* 列表 */}
  154.         ‹List list={list} checkHandler={this.checkHandler} delHandler={this.delHandler}>‹/List>
  155.         {/* 统计 */}
  156.         ‹Total checkAllHandler={this.checkAllHandler.bind(this)} checkAll={checkAll} selectLength={selectLength}>‹/Total>
  157.         {/* 编辑弹框 */}
  158.         { flag ? ‹Mask >‹/Mask> : ''}
  159.       ‹/div>
  160.     )
  161.   }
  162. }
复制代码
Input.js
  1. import React, { Component } from 'react'
  2. import { bus as $bus } from './bus'
  3. export default class Input extends Component {
  4.   constructor() {
  5.     super()
  6.     this.state = {
  7.       value:""
  8.     }
  9.   }
  10.   changeHandler = (e)=>{
  11.     this.setState({
  12.       value: e.target.value
  13.     })
  14.     console.log("this.state.value",this.state.value);
  15.   }
  16.   // 添加
  17.   addHandler = ()=>{
  18.     let { value } = this.state;
  19.     let obj = {
  20.       id: Date.now(),
  21.       content: value,
  22.       done: false
  23.     }
  24.     if(value) {
  25.       $bus.emit("sendValue",obj)
  26.     } else {
  27.       console.log("请输入")
  28.     }
  29.   }
  30.   // 搜索
  31.   searchHandler = ()=>{
  32.     console.log("搜索");
  33.     let { value } = this.state;
  34.     if(!value) return console.log("请输入");
  35.     $bus.emit("searchValue",value)
  36.   }
  37.   render() {
  38.     let { value } = this.state
  39.     return (
  40.       ‹>
  41.         ‹div className="input">
  42.           ‹input type="text" value={value} placeholder='请输入你的任务名称,按回车键确认' onInput={this.changeHandler}/>
  43.           ‹button className="btn btn-success" onClick={this.addHandler}>添加‹/button>
  44.           ‹button className="btn btn-primary" onClick={this.searchHandler}>搜索‹/button>
  45.         ‹/div>
  46.       ‹/>
  47.     )
  48.   }
  49. }
复制代码
List.js
  1. import React, { Component } from 'react'
  2. import Item from './Item'
  3. import PropTypes from 'prop-types'
  4. export default class List extends Component {
  5.   static propTypes = {
  6. list:PropTypes.array.isRequired,
  7. }
  8.   render() {
  9.     let { list,checkHandler,checkAllHandler,delHandler } = this.props;
  10.     console.log("list",list);
  11.     return (
  12.       ‹ul className="task-list">
  13.         {
  14.           list.map(item => (‹Item item={item} key={item.id} checkHandler={checkHandler} checkAllHandler={checkAllHandler} delHandler={delHandler}>‹/Item>))
  15.         }
  16.       ‹/ul>
  17.     )
  18.   }
  19. }
复制代码
Item.js
  1. import React, { Component } from 'react'
  2. import { bus as $bus } from './bus'
  3. export default class Item extends Component {
  4.   constructor(props) {
  5.     super(props)
  6.     this.state = {}
  7.   }
  8.   changeHandler = (id)=>{
  9.     let { checkHandler } = this.props;
  10.     return (e)=>{
  11.       checkHandler(id,e.target.checked)
  12.     }
  13.   }
  14.   removeHandler(){
  15.     let { delHandler } = this.props;
  16.     delHandler(arguments[0])
  17.   }
  18.   editHadnler = (item)=>{
  19.     $bus.emit("getFlag",true)
  20.     localStorage.setItem("obj",JSON.stringify(item))
  21.     $bus.emit("getItem",item)
  22.   }
  23.   render() {
  24.     let { item } = this.props;
  25.     return (
  26.       ‹li className="task-item">
  27.         ‹input type="checkbox" checked={item.checked} onChange={this.changeHandler(item.id)}/>
  28.         ‹div className="content">
  29.           {item.content}
  30.         ‹/div>
  31.         ‹button className={`btn btn-success ${!item.checked ? "d-none" : "d-block"}`} onClick={()=> this.editHadnler(item)}>编辑‹/button>
  32.         ‹button className={`btn btn-danger ${!item.checked ? "d-none" : "d-block"}`} onClick={this.removeHandler.bind(this,item.id)}>删除‹/button>
  33.       ‹/li>
  34.     )
  35.   }
  36. }
复制代码
Total.js
  1. import React, { Component } from 'react'
  2. export default class Total extends Component {
  3.   constructor() {
  4.     super()
  5.     this.changeAllHandler = this.changeAllHandler.bind(this)
  6.   }
  7.   changeAllHandler(e) {
  8.     let { checkAllHandler } = this.props
  9.     checkAllHandler(e.target.checked)
  10.   }
  11.   render() {
  12.     let { checkAll,selectLength } = this.props;
  13.     return (
  14.       ‹div className="task-done">
  15.         ‹input type="checkbox" onChange={this.changeAllHandler} checked={checkAll}/>
  16.         ‹p>已完成‹span className="single-number">{selectLength}‹/span> 全部‹span className="all-number">4‹/span>‹/p>
  17.       ‹/div>
  18.     )
  19.   }
  20. }
复制代码
Mask.js(弹窗)
  1. import React, { Component } from 'react'
  2. import { bus as $bus } from './bus'
  3. export default class mask extends Component {
  4.   constructor() {
  5.     super()
  6.     this.state = {
  7.       value: ''
  8.     }
  9.   }
  10.   closeMask = ()=>{ // 关闭弹窗
  11.     $bus.emit("getFlag",false)
  12.   }
  13.   updateHandler = ()=>{
  14.     $bus.emit("getFlag",false)
  15.     $bus.emit("update",this.state.value)
  16.   }
  17.   onChange = (e) =>{
  18.     this.setState({
  19.       value: e.target.value
  20.     })
  21.   }
  22.   componentDidMount() {
  23.     let obj = JSON.parse(localStorage.getItem("obj"))
  24.     this.setState({
  25.       value: obj.content
  26.     })
  27.   }
  28.   render() {
  29.     let { value } = this.state
  30.     return (
  31.       ‹div>
  32.         ‹div className="mm-mask" >
  33.         ‹div className="mm-modal">
  34.           ‹div className="mm-title">
  35.             ‹span className="mm-edit">编辑‹/span>
  36.             ‹span className="mm-close" onClick={this.closeMask}>x‹/span>
  37.           ‹/div>
  38.           ‹div className="mm-content">
  39.             ‹input type="text" value={value} placeholder="任务名称" onInput={this.onChange}/>
  40.           ‹/div>
  41.           ‹div className="mm-box-btn">
  42.             ‹div className="mm-update" onClick={this.updateHandler}>更新‹/div>
  43.             ‹div className="mm-cancel" onClick={this.closeMask}>取消‹/div>
  44.           ‹/div>
  45.         ‹/div>
  46.       ‹/div>
  47.       ‹/div>
  48.     )
  49.   }
  50. }
复制代码
bus.js
  1. yarn add -D events
  2. import { EventEmitter } from 'events'
  3. export const bus = new EventEmitter() // 导出bus实例
复制代码
App.css
  1. * {
  2.   margin: 0;
  3.   padding: 0;
  4. }
  5. input,button {
  6.   outline: none;
  7.   border: 0;
  8. }
  9. ul>li {
  10.   list-style: none;
  11. }
  12. .container {
  13.   width: 400px;
  14.   height: 500px;
  15.   margin: 10px auto auto;
  16.   padding: 20px;
  17.   box-sizing: border-box;
  18.   color: #3333;
  19.   border: 1px solid;
  20.   overflow: hidden;
  21. }
  22. .input {
  23.   width: 100%;
  24.   height: 30px;
  25.   display: flex;
  26. }
  27. input {
  28.   width: 100%;
  29.   height: 100%;
  30.   border: 1px solid #e1e1e1;
  31.   box-sizing: border-box;
  32.   border-radius: 4px;
  33.   padding: 0 10px;
  34. }
  35. input::placeholder {
  36.   color: #e1e1e1;
  37. }
  38. input:focus {
  39.   border: 1px solid #0096e6;
  40. }
  41. .task-list {
  42.   width: 100%;
  43.   display: flex;
  44.   flex-flow: column wrap;
  45.   margin-top: 10px;
  46. }
  47. .task-list li {
  48.   display: flex;
  49.   height: 40px;
  50.   justify-content: center;
  51.   align-items: center;
  52.   padding: 0 10px;
  53.   background-color: #eef0f4;
  54.   margin-bottom: 10px;
  55.   overflow: hidden;
  56.   text-overflow: ellipsis;
  57.   white-space: nowrap;
  58. }
  59. .task-list li input[type^="checkbox"] {
  60.   width: 15px;
  61.   height: 15px;
  62.   border: 1px solid #e1e1e1;
  63.   cursor: pointer;
  64.   flex-shrink: 0;
  65. }
  66. .task-list li .content {
  67.   flex: 1;
  68.   margin-left: 10px;
  69. }
  70. .btn {
  71.   flex-shrink: 0;
  72.   display: flex;
  73.   align-items: center;
  74.   height: 30px;
  75.   justify-content: center;
  76.   padding: 5px 10px;
  77.   text-align: center;
  78.   cursor: pointer;
  79.   border-radius: 4px;
  80.   color: #fff;
  81.   letter-spacing: 2px;
  82.   margin: 0 5px;
  83.   box-sizing: border-box;
  84.   font-size: 16px;
  85. }
  86. .btn-success {
  87.   background-color: #0f0;
  88. }
  89. .btn-danger {
  90.   background-color: #f00;
  91. }
  92. .btn-primary {
  93.   background-color: #0096e6;
  94. }
  95. .task-done {
  96.   width: 100%;
  97.   height: 40px;
  98.   line-height: 40px;
  99.   display: flex;
  100.   align-items: center;
  101.   background-color: #eef0f4;
  102.   padding-left: 10px;
  103.   box-sizing: border-box;
  104.   margin-top: 30px;
  105. }
  106. .task-done input {
  107.   width: 15px;
  108.   height: 15px;
  109.   border: 1px solid #e1e1e1;
  110.   cursor: pointer;
  111.   flex-shrink: 0;
  112.   margin-right: 10px;
  113. }
  114. .single-number {
  115.   color: #333;
  116.   margin-left: 5px;
  117. }
  118. .all-number {
  119.   color: red;
  120.   margin-left: 5px;
  121. }
  122. .mm-mask{
  123.   position:fixed;
  124.   top:0;
  125.   left:0;
  126.   right:0;
  127.   bottom:0;
  128.   background:rgba(0,0,0,0.5);
  129. }
  130. .mm-modal{
  131.   width:350px;
  132.   position:absolute;
  133.   top:50%;
  134.   left:50%;
  135.   transform:translate(-50%,-50%);
  136.   z-index:1000;
  137.   background:#ffffff;
  138.   border-radius:4px;
  139.   color:#333333;
  140. }
  141. .mm-title {
  142.   height:50px;
  143.   line-height:50px;
  144.   display:flex;
  145.   justify-content:space-between;
  146.   border-bottom:1px solid #e1e1e1;
  147.   box-sizing:border-box;
  148.   font-size:20px;
  149. }
  150. .mm-edit{
  151.   text-indent:20px;
  152. }
  153. .mm-close{
  154.   margin-right:20px;
  155.   font-family:consals;
  156.   cursor:pointer;
  157. }
  158. .mm-content{
  159.   padding:0 20px;
  160.   margin-bottom:20px;
  161. }
  162. .mm-content input{
  163.   width:100%;
  164.   height:30px;
  165.   line-height:30px;
  166.   text-indent:20px;
  167.   border-radius:4px;
  168.   margin-top:20px;
  169.   border:1px solid #666;
  170.   box-sizing:border-box;
  171. }
  172. .mm-content input:hover{
  173.   border:1px solid #0096e6;
  174. }
  175. .mm-content input:last-child{
  176.   text-indent:5px;
  177. }
  178. .mm-box-btn{
  179.   display:flex;
  180. }
  181. .mm-update,.mm-cancel{
  182.   width:80px;
  183.   height:30px;
  184.   line-height:30px;
  185.   text-align: center;
  186.   cursor:pointer;
  187.   background:#0096e6;
  188.   color:#ffffff;
  189.   user-select:none;
  190.   border-radius:4px;
  191.   margin:0 20px 50px;
  192. }
  193. .mm-update{
  194.   margin-right:10px;
  195. }
  196. .d-none {
  197.   display: none;
  198. }
  199. .d-block {
  200.   display: block;
  201. }
复制代码
总结

  本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|耀极客论坛 ( 粤ICP备2022052845号-2 )|网站地图

GMT+8, 2022-11-28 19:27 , Processed in 0.072656 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表