zoukankan      html  css  js  c++  java
  • React == 实现简易购物车

    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} 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;
        }
    }
    
    }
  • 相关阅读:
    图片下落效果
    处理springmvc的post和get提交参数乱码问题
    nginx 安装
    xml学习总结(二)
    xml学习总结(一)
    psp系统需求分析
    MySQL Workbench “Error Code: 1175”
    mysql 连接两列
    php UNIX时间戳转换为指定日期格式
    drupal错误: Maximum execution time of 240 seconds exceeded
  • 原文地址:https://www.cnblogs.com/rabbit-lin0903/p/11603084.html
Copyright © 2011-2022 走看看