網(wǎng)站首頁 編程語言 正文
以todolist為例
目錄如下
app.js
import React, { PureComponent } from 'react' import Input from './components/Input' import List from './components/List' import Total from './components/Total' import Mask from './components/Mask' import { bus as $bus } from './components/bus' import './App.css' export default class App extends PureComponent { constructor() { super() this.state = { flag: false, list: [ { id: 1, content: '哈哈哈', checked: false }, { id: 7, content: '哈哈哈', checked: false }, { id: 5, content: '哈哈哈', checked: false }, ], checkAll: false, selectLength: 0, item: {} } } // 全選全不選 checkAllHandler(checked) { console.log("checked",checked); const { list } = this.state const newList = list.map(item =>{ return {...item,checked} }) this.setState({list:newList,checkAll: checked},()=>{ this.doneLenth() }) } // 單選單不選 checkHandler =(id,checked)=> { const { list } = this.state const newList = list.map(item => { return item.id === id ? {...item,checked} : item }) let checkAll = newList.length && newList.every(item => item.checked) this.setState(() => ({list: newList,checkAll}),()=>{ this.doneLenth() }) } // 添加 addHandler = (obj)=>{ let { list } = this.state; let newList = [...list,obj] console.log('newList===='+newList) this.setState({ list: newList, },()=>{ this.doneLenth() }) } // 搜索 searchHandler=(content)=>{ console.log("content",content); let { list } = this.state; let newList = list.filter(item => item.content.includes(content)) this.setState({ list: newList },()=>{ this.doneLenth() }) } // 刪除 delHandler = (id)=> { console.log("id",id); const { list } = this.state const newList = list.filter(item => item.id !=id) let checkAll = newList.length && newList.every(item => item.checked) this.setState(() => ({list: newList,checkAll}),()=>{ this.doneLenth() }) } // 編輯 editHandler = (items)=>{ this.setState({ item: items }) } // 更新 update = (content)=>{ const { list,item } = this.state let obj = Object.assign(item,{content}) const newList = list.map(v =>{ if(v.id === obj.id) { v = {...obj} } return v }) this.setState({ list: newList, item: obj }) } // 已完成 doneLenth=()=> { const { list } = this.state const newList = list.filter(item => item.checked) let selectLength = newList.length setTimeout(()=>{ this.setState({ selectLength }) }) } // 掛載 componentDidMount() { this.unSubscribe = $bus.addListener("getFlag",(flag)=>{ this.setState({flag}) }) this.unSubscribe1 = $bus.addListener("sendValue",(obj)=>{ this.addHandler(obj) }) this.unSubscribe2 = $bus.addListener("searchValue",(value)=>{ this.searchHandler(value) }) this.unSubscribe3 = $bus.addListener("getItem",(item)=>{ this.editHandler(item) }) this.unSubscribe4 = $bus.addListener("update",(content)=>{ this.update(content) }) } // 卸載 componentWillUnmount() { $bus.removeListener(this.unSubscribe) $bus.removeListener(this.unSubscribe1) $bus.removeListener(this.unSubscribe2) $bus.removeListener(this.unSubscribe3) $bus.removeListener(this.unSubscribe4) } render() { let { flag, list,checkAll,selectLength } = this.state return ( <div className='container'> {/* 輸入框 */} <Input></Input> {/* 列表 */} <List list={list} checkHandler={this.checkHandler} delHandler={this.delHandler}></List> {/* 統(tǒng)計 */} <Total checkAllHandler={this.checkAllHandler.bind(this)} checkAll={checkAll} selectLength={selectLength}></Total> {/* 編輯彈框 */} { flag ? <Mask ></Mask> : ''} </div> ) } }
Input.js
import React, { Component } from 'react' import { bus as $bus } from './bus' export default class Input extends Component { constructor() { super() this.state = { value:"" } } changeHandler = (e)=>{ this.setState({ value: e.target.value }) console.log("this.state.value",this.state.value); } // 添加 addHandler = ()=>{ let { value } = this.state; let obj = { id: Date.now(), content: value, done: false } if(value) { $bus.emit("sendValue",obj) } else { console.log("請輸入") } } // 搜索 searchHandler = ()=>{ console.log("搜索"); let { value } = this.state; if(!value) return console.log("請輸入"); $bus.emit("searchValue",value) } render() { let { value } = this.state return ( <> <div className="input"> <input type="text" value={value} placeholder='請輸入你的任務(wù)名稱,按回車鍵確認' onInput={this.changeHandler}/> <button className="btn btn-success" onClick={this.addHandler}>添加</button> <button className="btn btn-primary" onClick={this.searchHandler}>搜索</button> </div> </> ) } }
List.js
import React, { Component } from 'react' import Item from './Item' import PropTypes from 'prop-types' export default class List extends Component { static propTypes = { list:PropTypes.array.isRequired, } render() { let { list,checkHandler,checkAllHandler,delHandler } = this.props; console.log("list",list); return ( <ul className="task-list"> { list.map(item => (<Item item={item} key={item.id} checkHandler={checkHandler} checkAllHandler={checkAllHandler} delHandler={delHandler}></Item>)) } </ul> ) } }
Item.js
import React, { Component } from 'react' import { bus as $bus } from './bus' export default class Item extends Component { constructor(props) { super(props) this.state = {} } changeHandler = (id)=>{ let { checkHandler } = this.props; return (e)=>{ checkHandler(id,e.target.checked) } } removeHandler(){ let { delHandler } = this.props; delHandler(arguments[0]) } editHadnler = (item)=>{ $bus.emit("getFlag",true) localStorage.setItem("obj",JSON.stringify(item)) $bus.emit("getItem",item) } render() { let { item } = this.props; return ( <li className="task-item"> <input type="checkbox" checked={item.checked} onChange={this.changeHandler(item.id)}/> <div className="content"> {item.content} </div> <button className={`btn btn-success ${!item.checked ? "d-none" : "d-block"}`} onClick={()=> this.editHadnler(item)}>編輯</button> <button className={`btn btn-danger ${!item.checked ? "d-none" : "d-block"}`} onClick={this.removeHandler.bind(this,item.id)}>刪除</button> </li> ) } }
Total.js
import React, { Component } from 'react' export default class Total extends Component { constructor() { super() this.changeAllHandler = this.changeAllHandler.bind(this) } changeAllHandler(e) { let { checkAllHandler } = this.props checkAllHandler(e.target.checked) } render() { let { checkAll,selectLength } = this.props; return ( <div className="task-done"> <input type="checkbox" onChange={this.changeAllHandler} checked={checkAll}/> <p>已完成<span className="single-number">{selectLength}</span> 全部<span className="all-number">4</span></p> </div> ) } }
Mask.js(彈窗)
import React, { Component } from 'react' import { bus as $bus } from './bus' export default class mask extends Component { constructor() { super() this.state = { value: '' } } closeMask = ()=>{ // 關(guān)閉彈窗 $bus.emit("getFlag",false) } updateHandler = ()=>{ $bus.emit("getFlag",false) $bus.emit("update",this.state.value) } onChange = (e) =>{ this.setState({ value: e.target.value }) } componentDidMount() { let obj = JSON.parse(localStorage.getItem("obj")) this.setState({ value: obj.content }) } render() { let { value } = this.state return ( <div> <div className="mm-mask" > <div className="mm-modal"> <div className="mm-title"> <span className="mm-edit">編輯</span> <span className="mm-close" onClick={this.closeMask}>x</span> </div> <div className="mm-content"> <input type="text" value={value} placeholder="任務(wù)名稱" onInput={this.onChange}/> </div> <div className="mm-box-btn"> <div className="mm-update" onClick={this.updateHandler}>更新</div> <div className="mm-cancel" onClick={this.closeMask}>取消</div> </div> </div> </div> </div> ) } }
bus.js
yarn add -D events import { EventEmitter } from 'events' export const bus = new EventEmitter() // 導(dǎo)出bus實例
App.css
* { margin: 0; padding: 0; } input,button { outline: none; border: 0; } ul>li { list-style: none; } .container { width: 400px; height: 500px; margin: 10px auto auto; padding: 20px; box-sizing: border-box; color: #3333; border: 1px solid; overflow: hidden; } .input { width: 100%; height: 30px; display: flex; } input { width: 100%; height: 100%; border: 1px solid #e1e1e1; box-sizing: border-box; border-radius: 4px; padding: 0 10px; } input::placeholder { color: #e1e1e1; } input:focus { border: 1px solid #0096e6; } .task-list { width: 100%; display: flex; flex-flow: column wrap; margin-top: 10px; } .task-list li { display: flex; height: 40px; justify-content: center; align-items: center; padding: 0 10px; background-color: #eef0f4; margin-bottom: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .task-list li input[type^="checkbox"] { width: 15px; height: 15px; border: 1px solid #e1e1e1; cursor: pointer; flex-shrink: 0; } .task-list li .content { flex: 1; margin-left: 10px; } .btn { flex-shrink: 0; display: flex; align-items: center; height: 30px; justify-content: center; padding: 5px 10px; text-align: center; cursor: pointer; border-radius: 4px; color: #fff; letter-spacing: 2px; margin: 0 5px; box-sizing: border-box; font-size: 16px; } .btn-success { background-color: #0f0; } .btn-danger { background-color: #f00; } .btn-primary { background-color: #0096e6; } .task-done { width: 100%; height: 40px; line-height: 40px; display: flex; align-items: center; background-color: #eef0f4; padding-left: 10px; box-sizing: border-box; margin-top: 30px; } .task-done input { width: 15px; height: 15px; border: 1px solid #e1e1e1; cursor: pointer; flex-shrink: 0; margin-right: 10px; } .single-number { color: #333; margin-left: 5px; } .all-number { color: red; margin-left: 5px; } .mm-mask{ position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.5); } .mm-modal{ width:350px; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:1000; background:#ffffff; border-radius:4px; color:#333333; } .mm-title { height:50px; line-height:50px; display:flex; justify-content:space-between; border-bottom:1px solid #e1e1e1; box-sizing:border-box; font-size:20px; } .mm-edit{ text-indent:20px; } .mm-close{ margin-right:20px; font-family:consals; cursor:pointer; } .mm-content{ padding:0 20px; margin-bottom:20px; } .mm-content input{ width:100%; height:30px; line-height:30px; text-indent:20px; border-radius:4px; margin-top:20px; border:1px solid #666; box-sizing:border-box; } .mm-content input:hover{ border:1px solid #0096e6; } .mm-content input:last-child{ text-indent:5px; } .mm-box-btn{ display:flex; } .mm-update,.mm-cancel{ width:80px; height:30px; line-height:30px; text-align: center; cursor:pointer; background:#0096e6; color:#ffffff; user-select:none; border-radius:4px; margin:0 20px 50px; } .mm-update{ margin-right:10px; } .d-none { display: none; } .d-block { display: block; }
總結(jié)
原文鏈接:https://blog.csdn.net/lxs19930928/article/details/122117796
相關(guān)推薦
- 2022-11-22 Oracle在表中有數(shù)據(jù)的情況下修改字段類型或長度的解決方法_oracle
- 2023-04-24 React組件與事件的創(chuàng)建使用教程_React
- 2022-10-29 SQL?Server主鍵約束(PRIMARY?KEY)_MsSql
- 2022-06-14 Pycharm安裝第三方庫的超詳細步驟_python
- 2022-05-27 android實現(xiàn)簡單拼圖游戲_Android
- 2022-06-02 Android?Apk反編譯及加密教程_Android
- 2022-05-12 Echarts x軸標(biāo)簽太長解決方案
- 2022-10-22 python常用數(shù)據(jù)結(jié)構(gòu)字典梳理_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支