欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

react实现todolist的增删改查详解

程序员文章站 2022-06-19 17:44:31
目录以todolist为例目录如下app.jsinput.jslist.jsitem.jstotal.jsmask.js(弹窗)bus.jsapp.css总结以todolist为例目录如下app.js...

以todolist为例

react实现todolist的增删改查详解

react实现todolist的增删改查详解

目录如下

react实现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>
        {/* 统计 */}
        <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='请输入你的任务名称,按回车键确认' 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 = ()=>{ // 关闭弹窗
    $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="任务名称" 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() // 导出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;
}

总结

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