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