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

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM