React快速上手购物车demo逻辑练习(快速复习react)15。

npx create-react-app my-app
cd my-app
npm start

购物车功能,本项目基于react进行开发有全选反选封装了footer和list 组件 reduce 计算总价,input 搜索功能,全选删除,单个删除,事件传值,写法清新通俗易通非常适合新手。

 App.jsx 主文件上代码

import React from 'react';
import './App.css';
import List from './component/list';
// react 的坑组件的名字首字母要大写
import Footer from './component/appFooter.jsx'

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      cardList: [{
          img: 'https://tse3-mm.cn.bing.net/th/id/OIP-C.yEH5M2URYGB8h62jG7vKGgHaHa?w=182&h=182&c=7&r=0&o=5&dpr=1.25&pid=1.7',
          name: 'Mac Book Air',
          num: 1,
          price: 8699,
          checked: false,
          id: 242332432432
        },
        {
          img: 'https://assets.ugoshop.com/proimage/e57f7e5856ad4c5aac37d5e349533bec.png!p800',
          name: 'iphone',
          num: 1,
          price: 37,
          checked: false,
          id: 242332432432421425
        }, {
          img: 'https://tse1-mm.cn.bing.net/th/id/OIP-C.rVdqtj7tUn6PClsn8Wq7xgHaKc?w=144&h=203&c=7&r=0&o=5&dpr=1.25&pid=1.7',
          name: '周虎青',
          num: 1,
          price: 4,
          checked: false,
          id: 355345435
        },
        {
          img: 'https://tse2-mm.cn.bing.net/th/id/OIP-C.keB_ghNAu-NyKNg7J2b0SQHaHa?w=203&h=203&c=7&r=0&o=5&dpr=1.25&pid=1.7',
          name: '苏日咕嘎',
          num: 1,
          price: 81,
          checked: false,
          id: 242332421425
        },
        {
          img: 'https://uploadfile.bizhizu.cn/2014/0217/20140217072454651.jpg',
          name: '孙志豪',
          num: 1,
          price: 99999,
          checked: false,
          id: 532325
        },
        {
          img: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.Q8fesauwGpQDaJuAQgDovAHaKR?w=146&h=203&c=7&r=0&o=5&dpr=1.25&pid=1.7',
          name: '秦明佳',
          num: 1,
          price: 88,
          checked: false,
          id: 5323255235
        },
      ],
      checkedAllFlag: false,
      local: []
    }
  }


  componentWillMount() {
    this.state.local = this.state.cardList
    this.setState({
      local: this.state.local
    })
  }
  // 增加小计
  add = (val) => {
    console.log(val);
    this.state.cardList.forEach(item => {
      if (item.id == val.id) {
        item.num++
      }
    })
    this.setState({
      cardList: this.state.cardList
    })
  }
  // 减少小计
  sub = (val) => {
    this.state.cardList.forEach(item => {
      if (item.id == val.id && item.num > 1) {
        item.num--
      }
    })
    this.setState({
      cardList: this.state.cardList
    })
  }
  // 改变复选框的状态
  editChecked = (val) => {
    this.state.cardList.forEach(item => {
      if (item.id == val.id) {
        item.checked = !item.checked
      }
    })
    this.setState({
      cardList: this.state.cardList
    })
  }
  // 删除的逻辑
  deleteData = (val) => {
    this.state.cardList = this.state.cardList.filter(item => item.id != val.id)
    this.setState({
      cardList: this.state.cardList
    })
  }
  // 更改复选框的状态
  checkedAll = (val) => {
    console.log(val)
    this.state.cardList.forEach(item => {
      console.log(item.checked)
      item.checked = val
    })
    console.log(this.state.cardList)
    this.setState({
      cardList: this.state.cardList
    })
  }

  // 反选的状态
  editCheckedFlag = (val) => {
    console.log(val)
    this.state.checkedAllFlag = this.state.cardList.every(item => item.checked)
    this.setState({
      checkedAllFlag: this.state.checkedAllFlag
    })
    console.log(this.state.checkedAllFlag)
  }
  onsearch = (val) => {
    this.state.cardList = this.state.local.filter(item => item.name.includes(val.target.value))
    this.setState({
      cardList: this.state.cardList
    })
  }

  removeChecked = () => {
    this.state.cardList = this.state.cardList.filter(item => item.checked == false)
    this.state.checkedAllFlag =  false
    console.log(this.state.cardList)
    this.setState({
      cardList: this.state.cardList,
      checkedAllFlag:this.state.checkedAllFlag 
    })
  }


  render() {
    return <div className = 'box' > {
        /* 头部 */ } <
      div className = 'header' >
      <
      input onInput = {
        this.onsearch
      }
    placeholder = '输入内容进行查找'
    type = "text" / >
      <
      /div> {
        /* 列表 */ } <
      List editCheckedFlag = {
        this.editCheckedFlag
      }
    deleteData = {
      this.deleteData
    }
    editChecked = {
      this.editChecked
    }
    add = {
      this.add
    }
    sub = {
      this.sub
    }
    cardList = {
      this.state.cardList
    }
    /> {
      /* 底部 */ } <
    Footer removeChecked = {
      this.removeChecked
    }
    editCheckedFlag = {
      this.editCheckedFlag
    }
    checkedAllFlag = {
      this.state.checkedAllFlag
    }
    checkedAll = {
      this.checkedAll
    }
    cardList = {
      this.state.cardList
    }
    /> </div>
  }
}

src/components/list.jsx组件

import React from 'react'

export default class list extends React.Component {
    constructor(props){
        super(props) 
    }
    add = (val) => {
        let {add} = this.props
        console.log(val);
        add(val)
    }
    sub = (val) => {
        let {sub} = this.props
        console.log(val);
        sub(val)
    }
    editChecked = (val) => {
        let {editChecked,editCheckedFlag} = this.props
        editChecked(val)
        editCheckedFlag()
    }
    deleteData = (val) => {
        let {deleteData} = this.props
        deleteData(val)
    }
   
    render() {
        return <>
            <div className='list'> 
                <div>状态</div>
                <div> 产品编号</div>
                <div> 产品展示</div>
                     <div>展示名称</div>
                <div>购买数量</div>
                <div>产品单价</div>
                <div>产品总价</div>
                <div>操作</div>
             </div>
            {
                this.props.cardList.map((item,index) => {
                    return <div key={index}  className='list' > 
                        <div>
                        <input  onChange={this.editChecked.bind(this,item)} checked={item.checked} type="checkbox" name="" id="" />
                        </div>
                        <div>{index}</div>
                        <div> <img src={item.img}  alt="" /></div>
                        <div>{item.name}</div>
                        <div>
                            <button onClick={this.sub.bind(this,item)}>-</button>
                            <span>{ item.num}</span>
                            <button onClick={this.add.bind(this,item)}>+</button>
                        </div>
                        <div>
                            {item.price}元
                        </div>
                        <div>
                            {item.price * item.num }元
                        </div>
                        <div>
                            <button onClick={this.deleteData.bind(this,item)}>删除</button>
                        </div>
                       </div>
                })
            }
      </>
  }
}

src/components/footer.jsx组件

import React from 'react'

export default class list extends React.Component {
    constructor(props){
        super(props) 
    }
    subNum = ()=> {
     return this.props.cardList.reduce((num,item) => num += item.checked && item.num * item.price ,0)
    }
    Num = ()=> {
     return this.props.cardList.reduce((num,item) => num += item.checked && item.num  ,0)
    }
    // 更改全部状态
    checkedAll = (e) => {
        let { checkedAll ,editCheckedFlag} = this.props
        checkedAll(e.target.checked)
        editCheckedFlag()
    }
    // 删除列表
    removeChecked = (e) => {
        let { removeChecked } = this.props
        removeChecked()
    }
    render() {
        return <div className='footer'>
            <input onChange={this.checkedAll} checked={this.props.checkedAllFlag} type="checkbox" name="" id="" />
            <div>总计:{ this.subNum() }元 共 {  this.Num()} 件商品 <button onClick={this.removeChecked.bind(this)} >批量删除</button></div>
        </div>
    }
}

App.css

*{
  padding: 0;
  margin: 0;
}
.header{
  width: 100%;
  height: 40px;
  border-bottom: 1px solid #000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.header input {
  border: 1px solid rgb(53, 51, 51);
  width: 200px;
  height: 30px;
}
.box{
  width: 1500px;
  height: 800px;
  background-color: pink;
  padding: 20px;
  border-radius: 20px;
  margin:20px auto;
}
.list{
  width: 100%;
  height: 90px;
  border-bottom: 1px solid rgb(179, 174, 174);
  display: flex;
  align-items: center;
}
.list img {
  width: 80px;
  height: 80px;
  border-radius: 50%;
}
.list div{
  width: 260px;
  line-height:90px ;
  height: 100%;
}
.list  button{
  width: 60px;
  height: 30px;
}
.list span {
  width: 40px;
  text-align: center;
  display: inline-block;
}
.bg{
  background-color: rgb(246, 242, 242);
}
.footer{
  width: 100%;
  height: 90px;
  display: flex;
  align-items: center;
}
input {
  width: 20px;
  height: 20px;
}

szh

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有两把刷子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值