好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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 ;
    } 
}

} 

 

查看更多关于React == 实现简易购物车的详细内容...

  阅读:40次