美文网首页
前后分离:实现一个简易的购物流程

前后分离:实现一个简易的购物流程

作者: 最懒猫_e51d | 来源:发表于2019-04-21 21:15 被阅读0次

    这算一次复盘吧,接到的一个需求:前后分离,前端走完一个简单购物流程,然后最后将数据提交给后台。
    第一次写的时候写得挺混乱的,埋了不少坑,同事看不下去了,帮忙填了一次坑。o(╥﹏╥)o(真的不想坑人)
    后面自己整理了下思路,私下自己在重新写了一遍,这里记录一下.
    这次主要收获:
    1. 前后分离思想
    2. cookie的应用
    3. 改掉混乱的面条式代码,提升复用率,模块化编程


    需求分析
    • 首先,一共四个页面:
      首页——>产品列表页——>购物车页面——>结算页面
    • 需要实现的功能点:
      1. 在首页和产品列表页点击某产品可以加入购物车
      2. 如果该产品已经在购物车内则不能重复加入
      3. 每个页面头部购物车数量更新
      4. 在购物车页面时历遍出在购物车中的产品
      5. 计算以及显示 产品总价、运费、以及订单总价(运费+总价)
      6. 进入结算页面历遍出需要结算的产品和单价,以及更新产品总价,和订单总价(加运费);
      7. 加急运费,如果勾选加急运费则加上运费,如果不勾选则恢复。
      8. 如果所购买的产品中有Monthy产品,则显示相应协议,如果没有则不显示。
      9. 在结算页面提交时需要校验信息。

    具体实现

    1.建立一个JSON,存放产品的数据信息,如:

    var productInfo = {
        "product-des_1": "A bottle of drink",    //产品名字
        "product-des_2": "2 bottles of drinks",
        "product-des_3": "3 bottles of drinks",
        "product-des_4": "4 bottles of drinks",
        "product-des_5": "5 bottles of drinks",
        "product-des_6": "Buy one bottle a month"
        "product-price_1": 9.99,         //对应的产品价格
        "product-price_2": 19.99,
        "product-price_3": 29.99,
        "product-price_4": 39.99,
        "product-price_5": 49.99,
        "shipping-price"  : 8.00,       //加急运费
        "shipping-fee": 0               //运费
    };
    

    2.加入购物车

    当某产品点击加入购物车按钮时,传入对应产品的id,如:

    <a class="btn" onclick="addCart(3);">ADD TO CART</a>
    

    在接收这个id后,需要实现几个点:

    1. 创建一个对象作为产品,对象key值有[产品ID]、[产品名字]、[产品价格]、[是否是monthy产品]。
    2. 判断是否已经存有cookie,如果没有,则建立一个新数组,并push入新加的产品,并存储入cookie;
    3. 如果已有cookie,则取出cookie赋值给一个变量,历遍该变量。这里需要实现两个功能点:
      1. 判断这个产品是否加入过购物车
      2. 在历遍的同时,加出所有产品的总价。
    4. 如果购物车内没有此产品,则可以将改产品push入数组,并更新总价,然后存入cookie。
    5. 调用修改购物车个数。
    function addCart(productId){
        var productDes = "product-des_" + productId;
        var productPri = "product-price_" + productId;
        var proName = productInfo[productDes];
        var pPrice = productInfo[productPri];
        
        var products = {};
        products.id = productId;
        products.name = proName;
        products.price = pPrice;
        //判断是否是Monthy产品
        if(proName.indexOf('month') != -1){
            products.auto = 1;
        }
        
        if(typeof $.cookie('productList') == 'undefined'){
            var proList = [];
            proList.push(products);
            
            $.cookie('productList', JSON.stringify(proList));
            $.cookie('proTotal', pPrice.toFixed(2));
        }else{
            var proList = JSON.parse($.cookie('productList'));
            var isAdd = true;
            var pTotal = 0;
            
            for(let i=0; i<proList.length; i++){
                let p = proList[i];
                if(p.id == productId){
                    isAdd = false;
                }
                
                pTotal = pTotal + p.price;
            }
            
            if(isAdd){
                proList.push(products);
                pTotal = pTotal + products.price;
                
                $.cookie('productList', JSON.stringify(proList));
                $.cookie('proTotal', pTotal.toFixed(2));
            }
        }
        
        //更新购物车数量
        innerCartCount();
        
    }
    

    3.修改购物车个数
    html页面上:

    <span>Cart(<b id="cartNum">0</b>)</span>
    

    首先需要判断页面上是否有这个元素(以防在其他页面调用的时候报错),并且需要判断是否存储了产品cookie。
    取出cookie赋值给变量,读取该变量的个数,并更改页面上的数量。

    function innerCartCount(){
        var cartNum = document.getElementById('cartNum');
        if(cartNum != null && cartNum != ''){
            if(typeof $.cookie('productList') != 'undefined'){
                var proList = JSON.parse($.cookie('productList'));
                var count = proList.length;
                
                cartNum.innerHTML = count;
            }
        }
    }
    

    在这里需要注意一定,除了加入购物车时调用外,也需要在外面调用这个函数,解决页面一刷新,数量就清零的尴尬问题。

    4.购物车页面

    历遍出所有产品(产品名字、价格、以及删除按钮)

    function innerCartBodyHtml(){
        var cartBody = document.getElementById('cartBody');
        if(cartBody != null && cartBody != ''){
            if(typeof $.cookie('productList') != 'undefined'){
                var proList = JSON.parse($.cookie('productList'));
                var html = '';
                
                for(let i=0; i<proList.length; i++){
                    let p = proList[i];
                    html = html + `
                        <tr>
                            <td>${p.name}</td>
                            <td>${p.price}</td>
                            <td class='remove'>
                                <a class="btn btn-default" onclick="removeCart(${p.id},this)">remove</a>
                            </td>
                        </tr>
                    `
                }
                
                cartBody.innerHTML = html;
            }
        }
    }
    

    更新页面产品总价、运费、以及订单总价。

    function innerPrice(){
        if(typeof $.cookie('proTotal') != 'undefined'){
            var proTotal = Number($.cookie('proTotal'));
            
            //产品总价
            var subTotal = document.getElementById('subTotal');
            if(subTotal != null && subTotal != ''){
                subTotal.innerHTML = '$' + proTotal.toFixed(2);
            }
            
            //运费
            var shipFee = document.getElementById('shipFee');
            if(shipFee != null && shipFee != ''){
                var shipFeePrice = Number(productInfo['shipping-fee']);
                shipFee.innerHTML = shipFeePrice.toFixed(2);
            }
            
            //订单总价
            var orderTotal = document.getElementById('orderTotal');
            if(orderTotal != null && orderTotal != ''){
                var oTotal = proTotal + shipFeePrice;
                
                $.cookie('orderTotal',oTotal.toFixed(2));
                orderTotal.innerHTML = '$' + oTotal.toFixed(2);
            }
            
        }
    }
    

    删除购物车产品:

    1. 点击删除按钮时,传入该产品id以及this。
    2. 取出cookie以及总价,赋值给个数组,并历遍该数组,这里需要实现2点:
      1. 如果产品id与传入的id相同,则从数组中删除该元素。
      2. 总价减去改产品价格,更新cookie。
    3. 删除页面元素,更新页面价格,更新购物车个数。
    function removeCart(productId, obj){
        if(typeof $.cookie('productList') != 'undefined'){
            var proList = JSON.parse($.cookie('productList'));
            var pTotal = Number($.cookie('proTotal'));
            
            for(let i=0; i<proList.length; i++){
                let p = proList[i];
                if(p.id == productId){
                    proList.splice(i,1);
                    pTotal = pTotal - p.price;
                    
                    $.cookie('productList', JSON.stringify(proList));
                    $.cookie('proTotal', pTotal.toFixed(2));
                }
            }
            
            //删除页面元素
            var cartTr = obj.parentNode.parentNode;
            var cartTbody = cartTr.parentNode;
            cartTbody.removeChild(cartTr);
            
            //更新价格
            innerPrice();
            
            //更新购物车数量
            innerCartCount();
        }
    }
    
    

    5.结算页面

    结算页面需要历遍出需要结算的产品,和购物车的历遍差不多,但是这里不能删除,只要产品名和价格。

    function innerCheckoutProductListHtml(){
        var checkoutProList = document.getElementById('checkoutProductList');
        if(checkoutProList != null && checkoutProList != ''){
            if(typeof $.cookie('productList') != 'undefined'){
                var proList = JSON.parse($.cookie('productList'));
                var html = '';
                for(let i=0; i<proList.length; i++){
                    let p = proList[i];
                    html = html + `
                        <li>
                            <span class="pull-left">${p.name}</span>
                            <span class="pull-right">${p.price}</span>
                        </li>
                    `
                }
                
                checkoutProList.innerHTML = html;
            }
        }
    }
    

    更新页面运费:
    这里主要是将页面显示运费处写活,至于产品总价和订单已经写过,结算页面只需要加上对应id即可,不用重复写。

    function getShippingPrice(){
        var shippingPrice = document.getElementById('shippingPrice');
        if(shippingPrice != null && shippingPrice != ''){
            var shipPrice = Number(productInfo['shipping-price']);
            shippingPrice.innerHTML = '$' + shipPrice;
        }
    }
    

    是否勾选加急运费

    function fastshippingClick(){
        var fastShipping = document.getElementById('fastshipping');
        var orderTotal = document.getElementById('orderTotal');
        var ProtectPack = document.getElementById('ProtectPack');
        
        if(orderTotal != null && orderTotal != ''){
            if(typeof $.cookie('orderTotal') != 'undefined'){
                var oTotal = Number($.cookie('orderTotal'));
                
                if(fastShipping.checked){
                    oTotal = oTotal + Number(productInfo['shipping-price']);
                    orderTotal.innerHTML = '$' + oTotal.toFixed(2);
                    ProtectPack.value = 1;
                }else{
                    orderTotal.innerHTML = '$' + oTotal.toFixed(2);
                    ProtectPack.value = 0;
                }
            }
        }
    }
    

    是否存在Monthy产品,如果存在,显示出对应的条款说明,不存在则隐藏

    function checkSubs(){
        var chkSubs = document.getElementById('chk_subs');
        var proInfo = document.getElementById('proinfo');
        if(chkSubs != null && chkSubs != '' && proInfo != null && proInfo != ''){
            if(typeof $.cookie('productList') != 'undefined'){
                var html = '';
                var isShow = false;
                var proList = JSON.parse($.cookie('productList'));
                
                for(let i=0; i<proList.length; i++){
                    let p = proList[i];
                    if(p.auto == 1){
                        isShow = true;
                        html = html + `<li><b>${p.price} for Level 8 ${p.name}</b></li>`;
                    }
                }
                
                proInfo.innerHTML = html;
                
                //如果又monthy产品显示条款
                if(isShow){
                    chkSubs.style.display = 'block';    
                }
                
            }
        }
    }
    

    总结:

    一个简单的购物流程,其实主要的点就是在购物车添加删除以及数据的存取上。
    动手写代码前需要理清思路,思路清晰了,一个小点一个小点的写下来就会顺利很多,并且会避免遗漏。

    相关文章

      网友评论

          本文标题:前后分离:实现一个简易的购物流程

          本文链接:https://www.haomeiwen.com/subject/gjhsgqtx.html