React == 实现简易版购物车
1、几个要点:
为了方便后面使用input type = "checkbox" 实现复选框的选中/不选中,给传递过来的属性要在遍历的时候,单独加上一个新属性 checked?
count 属性 默认值 都是1.
state = {
all : false ,
sumprice :0 ,
one : false ,
sumcount:0
}?
state对象 :?
all -----> 用来定义全选按钮 sumprice -----> 用来定义总价 ? ? ? ?one -----> 用来控制 结算按钮的样式(当选中的其中任何一条购物车条目时候,显示橘色,当没有任何一条选中,显示灰色) ? ? ? ?sumcount ---->? 用来显示购物车的总数量,显示在页面中?
2、单选框的实现
1)首先是渲染的都是同样的样式,所以在这里传递一个index特别关键,通过index的传递才能够知道操作的是哪条
2)当onchange事件发生的时候,对当前checked属性进行取反。list[index].checked = ! list[index].checked。
3)单选框决定全选框:使用了数组的every方法(只有数组的每一项都满足条件,才会返回true),用所有datalist的单选框都是true的时候,全选按钮才会为true
4)单选框的选中与否决定结算框的样式:one : list[index].checked // 为true的时候,one : true?
<input?type="checkbox"?className={style.checkbtn+'?'+style.UnChecked}??ref="mytext"
? ? ? ? ? ?onChange={()=>{this.handleChange(index)}}?checked={item.checked}?value=""
? ? ?/>
// 单选 handleChange(index){ var list = [... this .state.datalist] list[index].checked = ! list[index].checked // every方法 var every=list.every((item,index)=> { return item.checked== true ; }) // 单选框中如果有一个是 checked的是true就可以 var some = list.some((item,index)=> { return list[index].checked }) this .setState({ datalist :list, all : every, // 全选按钮,只有当所有的list[index]=== true 的时候才会返回true one : some // 设定结算框的样式是哪个,根据list[index].checked }) this .SumPrice() }
?
3、全选按钮的实现
1)当点击全选框,对全选框的状态进行取反
2)点击全选按钮的时候,所有的单选框的为true / false 直接取决的 全选框按钮当前的状态true / false?
遍历所有的list[i].checked = all , 把全选框的状态(true/false)直接赋值给所有的list[i].checked 。?
3)当全选的时候,结算框的样式直接会跟随变动,当为false,即没有一个购物车条目呗选中,此时结算框的状态为灰色。当为true,结算框为橘色。
<input type="checkbox" onChange={()=>{ this .handleAll()}} checked={ this .state.all} value=""/>
// 全选
handleAll(){
var list = [... this .state.datalist]
var all = this .state.all
all = ! all //onchange事件发生,就是对当前的状态进行取反
for ( var i = 0 ; i < list.length ;i++ ){
list[i].checked = all // 全选框的状态直接影响所有的单选框,就把全选框的状态赋给所有的单选框即可
}
this .setState({
all : all,
one : all // 全选的状态直接影响结算框的样式
})
this .SumPrice()
}
?
4、购物车数量加减的实现
1)数量增加Add
重要的还是传递对应的index,才能准确地知道操作的是哪个购物车条目?
list[index].count++
2)数量减少Minus
还有进行一步判断,当此时购物车的数量已经是1的时候,不允许再继续减了
list[index].count--
list[index].count<1?1:list[index].count
<button className={style.minus} onClick={()=>{ this .handleMinus(index)}}>-</button>
<input type="text" value={ this .state.datalist[index].count||''}/>
<button className={style.add} onClick={()=>{ this .handleAdd(index)}}>+</button>
// 加
handleAdd(index){
// 设定的value= {this.state.datalist[index].count}
var list = [... this .state.datalist]
list[index].count ++ ;
this .setState({
datalist : list,
})
this .SumPrice()
}
// 减
handleMinus(index){
// 设定的value= {this.state.datalist[index].count}
var list = [... this .state.datalist];
list[index].count --
list[index].count =list[index].count<1?1 :list[index].count;
this .setState({
datalist : list
})
this .SumPrice()
}
?
5、总价的实现
1)遍历所有的datalist,只有当其中每一个checked属性为true的时候(表明已经被勾选上了,此时可以计算),才去计算金额
2)得到所有的总价,还能得到当前选中的数量一共有多少
SumPrice(){
var sum=0
var count = 0 ;
var list = [... this .state.datalist]
for ( var i =0; i< list.length ;i++ ){
if (list[i].checked=== true ){
sum += list[i].newprice * list[i].count
count += list[i].count
}
}
this .setState({
sumprice : sum,
sumcount : count // 结算个数
})
}
?
6、当进行 数量 的增加、减少、单选按钮、全选按钮的时候 都要重新调用计算总价的函数。
=============================================================================
完整代码:
JS >
class CartPage extends Component {
state = {
datalist:[
{
"imgUrl":"https://wochu.oss-cn-hangzhou.aliyuncs测试数据/upload/c8db2f99-d79e-4c4a-97e8-3e95c67a3b2e.jpg" ,
"name": "小青菜350g" ,
"newprice" : "4.5" ,
"oldprice" : "4.9" ,
"checked" : false ,
"count" :1
},
{
"imgUrl":"https://img.wochu.cn/upload/abbc6852-711f-4d09-8e61-216c13505ccd.jpg" ,
"name": "洪湖渔家香辣大闸蟹500g" ,
"newprice" : "15.9" ,
"oldprice" : "39.9" ,
"checked" : false ,
"count" :1
},
{
"imgUrl":"https://wochu.oss-cn-hangzhou.aliyuncs测试数据/upload/c8db2f99-d79e-4c4a-97e8-3e95c67a3b2e.jpg" ,
"name": "小青菜350g" ,
"newprice" : "4.5" ,
"oldprice" : "4.9" ,
"checked" : false ,
"count" :1
},
],
all : false ,
sumprice : 0 ,
one : false ,
sumcount: 0
}
render() {
return (
<div className={style.cartList}>
<div className={style.cartListItem}>
<ul className={style.shopList} ref="myul">
{ /* 对应的每个购物车条目 */ }
{
this .state.datalist.map((item,index)=>
<li key={index}>
<input type="checkbox" className={style.checkbtn+' '+style.UnChecked} ref="mytext"
onChange ={()=>{ this .handleChange(index)}} checked={item.checked} value=""
/>
<div className={style.shopImg}>
{ /* 点击图片跳转到页面详情 */ }
<div className={style.shopImgShow}>
<img src={item.imgUrl} alt=""/>
</div>
</div>
{ /* 商品详情 */ }
<div className={style.shopInfo}>
<div className={style.shopTitle}>{item.name}</div>
<div className={style.shopCoupen}></div>
<div className={style.shopPrice}>
<div className={style.price}>
<span>¥{item.newprice}</span>
<i>¥{item.oldprice}</i>
</div>
<div className={style.shopSelect}>
<button className={style.minus} onClick={()=>{ this .handleMinus(index)}}>-</button>
<input type="text" value={ this .state.datalist[index].count||''}/>
<button className={style.add} onClick={()=>{ this .handleAdd(index)}}>+</button>
</div>
</div>
</div>
</li>
)
}
</ul>
</div>
<div className={style.sum}>
<input type="checkbox" onChange={()=>{ this .handleAll()}} checked={ this .state.all} value=""/>
<div className={style.checkPrice}>
{ /* 合算 */ }
<div className={style.totalPrice}>
<span className={style.allsum}>合计</span>
<span>¥{ this .state.sumprice}</span>
</div>
{ /* 不含运费 */ }
<div className={style.fee}>(不含运费)</div>
</div>
{ /* 结算按钮 */ }
<div className={ this .state.one?style.btnCheck:style.btnNoCheck}> 结算
<span>({ this .state.sumcount})</span>
</div>
</div>
</div>
);
}
// 单选
handleChange(index){
var list = [... this .state.datalist]
list[index].checked = ! list[index].checked
var every=list.every((item,index)=> {
return item.checked== true ;
})
// 单选框中如果有一个是 checked的是true就可以
var some = list.some((item,index)=> {
return list[index].checked
})
this .setState({
datalist :list,
all : every,
one : some // 设定结算框的样式是哪个,根据list[index].checked
})
this .SumPrice()
}
// 全选
handleAll(){
var list = [... this .state.datalist]
var all = this .state.all
all = ! all
for ( var i = 0 ; i < list.length ;i++ ){
list[i].checked = all
}
this .setState({
all : all,
one : all // 全选的状态直接影响结算框的样式
})
this .SumPrice()
}
handleAdd(index){
// 设定的value= {this.state.datalist[index].count}
var list = [... this .state.datalist]
list[index].count ++ ;
this .setState({
datalist : list,
})
this .SumPrice()
}
handleMinus(index){
// 设定的value= {this.state.datalist[index].count}
var list = [... this .state.datalist];
list[index].count --
list[index].count =list[index].count<1?1 :list[index].count;
this .setState({
datalist : list
})
this .SumPrice()
}
SumPrice(){
var sum=0
var count = 0 ;
var list = [... this .state.datalist]
for ( var i =0; i< list.length ;i++ ){
if (list[i].checked=== true ){
sum += list[i].newprice * list[i].count
count += list[i].count
}
}
this .setState({
sumprice : sum,
sumcount : count // 结算个数
})
}
}
export default CartPage;
?
CSS >
.cartList {
background : #f4f5f7 ;
width : 100% ;
top : .99rem ;
.cartListItem{
width : 100% ;
background : #fff ;
margin-bottom : .04rem ;
// 购物车列表
.shopList{
width : 100% ;
// height : 1.11rem ;
padding : 0 .09rem ;
background : #fff ;
li{
width : 100% ;
height : 1.11rem ;
border-bottom : 1px solid #e6e6e6 ;
background : #fff ;
// 选中按钮
.checkbtn{
width : .17rem ;
height : 1.11rem ;
float : left ;
}
// 选中时候的类名
.UnChecked {
background : url("image/cart-img/unselect.png") no-repeat ;
background-size : 100% .25rem ;
}
// 点击图片跳转
.shopImg {
width : 1.1rem ;
height : 1.1rem ;
margin : 0 .1rem ;
float : left ;
.shopImgShow{
width : 1.1rem ;
height : 1.1rem ;
img{
width : 100% ;
}
}
}
// 购物车商品详情
.shopInfo {
width : 2.08rem ;
height : 1.1rem ;
padding : .1rem 0 ;
float : left ;
.shopTitle{
width : 100% ;
overflow : hidden ;
white-space : nowrap ;
text-overflow : ellipsis ;
height : .3rem ;
font-size : .14rem ;
}
.shopCoupen {
width : 2.08rem ;
height : .12rem ;
margin : .1rem 0 ;
}
.shopPrice {
width : 2.08rem ;
height : .25rem ;
//价格
.price{
width : 1.08rem ;
height : .21rem ;
float : left ;
span{
font-size : .15rem ;
color : #f96d16 ;
}
i {
font-size : .13rem ;
color : #999 ;
text-decoration : line-through ;
font-style : normal ;
}
}
// 按钮
.shopSelect {
float : right ;
width : .775rem ;
height : .25rem ;
.minus{
float : left ;
width : .225rem ;
height : .25rem ;
border : 0 ;
}
input {
float : left ;
width : .325rem ;
height : .25rem ;
text-align : center ;
border : 0 ;
}
.add {
float : left ;
width : .225rem ;
height : .25rem ;
border : 0 ;
}
}
}
}
}
}
}
// 合算
div.sum {
width : 100% ;
height : .5rem ;
background : #fff ;
padding-left : .1rem ;
position : fixed ;
bottom : .5rem ;
left : 0 ;
input{
height : 100% ;
float : left ;
}
.checkPrice {
float : left ;
width : 1.48rem ;
height : .41rem ;
line-height : .41rem ;
padding : .08rem 0 ;
margin-left : .1rem ;
// 合计
.totalPrice{
float : left ;
width : .869rem ;
height : .36rem ;
line-height : .36rem ;
font-size : .16rem ;
color : #f96d16 ;
.allsum{
font-size : .13rem ;
color : #333 ;
}
}
// 不含运费
.fee {
float : left ;
width : .61rem ;
font-size : .13rem ;
color : #999 ;
}
}
// 结算按钮
.btnCheck {
width : 1.15rem ;
height : .49rem ;
background : rgb(249, 109, 22) ;
float : right ;
line-height : .49rem ;
font-size : .18rem ;
color : #fff ;
text-align : center ;
}
.btnNoCheck {
width : 1.15rem ;
height : .49rem ;
background : rgb(153, 153, 153) ;
float : right ;
line-height : .49rem ;
font-size : .18rem ;
color : #fff ;
text-align : center ;
}
}
}
?
查看更多关于React == 实现简易购物车的详细内容...