Take todolist as an exampleThe directory is as followsapp.jsimport 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: 'Hahaha', checked: false }, { id: 7, content: 'Hahaha', checked: false }, { id: 5, content: 'Hahaha', checked: false }, ], checkAll: false, selectLength: 0, item: {} } } // Select all or unselect all 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.doneLength() }) } // Single-choice single-select 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.doneLength() }) } // add addHandler = (obj)=>{ let { list } = this.state; let newList = [...list,obj] console.log('newList===='+newList) this.setState({ list: newList, },()=>{ this.doneLength() }) } // Search searchHandler=(content)=>{ console.log("content",content); let { list } = this.state; let newList = list.filter(item => item.content.includes(content)) this.setState({ list: newList },()=>{ this.doneLength() }) } // Delete 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.doneLength() }) } // Edit editHandler = (items)=>{ this.setState({ item: items }) } // Update 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 }) } // Completed doneLenth=()=> { const { list } = this.state const newList = list.filter(item => item.checked) let selectLength = newList.length setTimeout(()=>{ this.setState({ selectLength }) }) } // Mount 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) }) } // Unmount 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 box*/} <Input></Input> {/* list */} <List list={list} checkHandler={this.checkHandler} delHandler={this.delHandler}></List> {/* Statistics */} <Total checkAllHandler={this.checkAllHandler.bind(this)} checkAll={checkAll} selectLength={selectLength}></Total> {/* Edit popup box */} { flag ? <Mask ></Mask> : ''} </div> ) } } Input.jsimport 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); } // add addHandler = ()=>{ let { value } = this.state; let obj = { id: Date.now(), content: value, done: false } if(value) { $bus.emit("sendValue",obj) } else { console.log("Please enter") } } // Search searchHandler = ()=>{ console.log("search"); let { value } = this.state; if(!value) return console.log("Please enter"); $bus.emit("searchValue",value) } render() { let { value } = this.state return ( <> <div className="input"> <input type="text" value={value} placeholder='Please enter your task name and press Enter to confirm' onInput={this.changeHandler}/> <button className="btn btn-success" onClick={this.addHandler}>Add</button> <button className="btn btn-primary" onClick={this.searchHandler}>Search</button> </div> </> ) } } List.jsimport 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.jsimport 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)}>Edit</button> <button className={`btn btn-danger ${!item.checked ? "d-none" : "d-block"}`} onClick={this.removeHandler.bind(this,item.id)}>Delete</button> </li> ) } } Total.jsimport 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>Completed<span className="single-number">{selectLength}</span> All<span className="all-number">4</span></p> </div> ) } } Mask.js (pop-up window)import React, { Component } from 'react' import { bus as $bus } from './bus' export default class mask extends Component { constructor() { super() this.state = { value: '' } } closeMask = ()=>{ // Close the pop-up window$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">Edit</span> <span className="mm-close" onClick={this.closeMask}>x</span> </div> <div className="mm-content"> <input type="text" value={value} placeholder="Task name" onInput={this.onChange}/> </div> <div className="mm-box-btn"> <div className="mm-update" onClick={this.updateHandler}>Update</div> <div className="mm-cancel" onClick={this.closeMask}>Cancel</div> </div> </div> </div> </div> ) } } bus.jsyarn add -D events import { EventEmitter } from 'events' export const bus = new EventEmitter() // Export bus instance 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; } SummarizeThis article ends here. I hope it can be helpful to you. I also hope you can pay more attention to more content on 123WORDPRESS.COM! You may also be interested in:
|
<<: Bootstrap 3.0 study notes for beginners
>>: What is html file? How to open html file
Table of contents 1. Project Description 2. Nginx...
Report an error The Apache\Nginx service started ...
Preface I believe that everyone has been developi...
1. Concat function. Commonly used connection stri...
1. There are generally two methods for Vue routin...
Table of contents Methods of String Object Method...
Basic environment configuration Please purchase t...
Table of contents 1. Introduction to PXC 1.1 Intr...
This article example shares the specific code for...
Table of contents 1. Computed properties Syntax: ...
In HTML, the <img> tag is used to define an...
Preface To solve the single point of failure, we ...
This article shares the specific code for impleme...
Summary of common operators and operators in java...
Note: Since .NET FrameWork cannot be run in core ...