当前位置 : 主页 > 网页制作 > React >

React == 实现简易购物车

来源:互联网 收集:自由互联 发布时间:2021-06-15
React == 实现简易版购物车 1、几个要点: 为了方便后面使用input type = "checkbox" 实现复选框的选中/不选中,给传递过来的属性要在遍历的时候,单独加上一个新属性 checked count 属性 默认

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.com/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.com/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} />
                                </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;
    }
}

}
网友评论