美文网首页
[vue]仿淘宝app购物车实现

[vue]仿淘宝app购物车实现

作者: Re_Vive | 来源:发表于2018-06-11 22:52 被阅读0次

根据需求要类似淘宝app的购物车实现。网上的例子一般都是一个产品列表就完成,但淘宝这些需要有一个对店铺的分类,所以复杂度提升一倍。


TIM图片20180608140218.png

1.对单个商品数量进行操作的时候,商品的价格变动,总价变动
2.点击产品选择,总价和数量变动,并且一个商店所以产品被选择时,商店的按钮为被选择状态
3.对一个商店做选择的时候,下面所有商品被选择,总价和数量变动,并且所有商店被选择的时,全选为被选择状态
4.全选的时候,所有店铺已经商品为被选择状态,总价和数量变动

<ul>
    <li v-for="item in carts">
        <div class="shoptitle">
            <!--选择商店的全部商品-->
            <span class="check" :class="{'checked':item.checked}" @click="checkShop(item)"></span>
            {{item.shopTitle}}
        </div>
        <div class="productlist">
            <ul>
                <li v-for="pros in item.productList">
                    <!--选择商品-->
                    <span class="check" :class="{'checked':pros.isChecked}" @click="ischeck(item,pros)">
                    </span>
                    <img src="" alt="" />
                    <div class="product">
                        <p class="producttitle">{{pros.productTitle}}</p>
                        <p class="category">{{pros.category}}</p>
                        <div class="price">
                            <!--使用过滤器对总价改变-->
                            <span>¥{{pros.price | totalprice(pros.count)}}</span>
                            <div class="count">
                                 <!--商品数量控制-->
                                <a herf="javascript:void(0)" class="btn-minus" @click="changeCount(pros,-1)">-</a>
                                <input type="number" v-model="pros.count">
                                <a herf="javascript:void(0)" class="btn-plus"  @click="changeCount(pros,1)">+</a>
                            </div>
                        </div>
                    </div>
                </li>
            </ul>
        </div>
    </li>
</ul>

<div class="paybox">
    <div class="payleft">
         <!--选择全部商品-->
        <span class="check" :class="{'checked':isCheckAll}" @click="checkAll()"></span>
        <b>全选</b>
    </div>

    <button>结算({{allCount}})</button>
    <span>总计:{{allPrice}}</span>
</div>

👆自己手写的布局,大概这个样子,主要是双重循环,对几个span的点击事件

carts:[
    {
        shopTitle:'苹果旗舰店',//商店名
        checked:false,//商店选择的状态
        checkedCount:0,//此商店被选择的商品数量
        productList:[
            {
                isChecked:false,//商品选择状态
                productTitle:'2019款macbook/苹果/MF893/A国航笔记本',//产品名
                category:'15寸/2.3/8G/256/土豪金/标准套餐',
                price:10200,//价格
                count:1//数量
            }
        ]
    },
    {
        shopTitle:'锤子科技旗舰店',
        checked:false,
        checkedCount:0,
        productList:[
            {
                isChecked:false,
                productTitle:'锤子手机手感保护膜',
                category:'登陆月球',
                price:9.9,
                count:1
            },
           {
                isChecked:false,
                productTitle:'锤子手机pro割手版',
                category:'128G/割手版',
                price:1790,
                count:1
            }
        ]
    }
],
isCheckAll:false,//是否全选
allPrice:0,//所有价格
allShops:0,//被选中的商店数量
allCount:0,//被选中的产品数量

👆先看数据,直接在data模拟的数据

changeCount(val,way){//判断way的值为1还是-1
    if (way>0){
        val.count++
    }else{
        val.count--
        if(val.count<1){
            val.count = 1
        }
    }
}
filters:{//单件商品的价格 × 数量
    totalprice(val,count){
        return val * count
    }
}

👆一个changeCount方法来改变商品数量,并用过滤器来返回单个商品的总价

ischeck(item,pro){//为未选中的时候改变为true,反之为true
    !pro.isChecked?this._checkTrue(item,pro):this._checkFalse(item,pro)
},
_checkTrue(item,pro){
    pro.isChecked = true//改变状态为true
    ++item.checkedCount == item.productList.length?item.checked = true:''
    //每选中一个商品,被选中的商品数加一,如果数值等于商品数,商店的全选状态为true
    item.checked?   ++this.allShops === this.carts.length ? this.isCheckAll = true : this.isCheckAll = false    : ''
    //当商店全选状态,每全选一个商店,被选中商店数加一,数值等于所有商店数,全选状态为true
},
_checkFalse(item,pro){
    pro.isChecked = false//改变状态为false
    --item.checkedCount//被选中的商品数减一
    if(item.checked){
        item.checked = false//当商店状态为选中时改变false
        --this.allShops//商店数减一
    }
    this.isCheckAll = false//全选状态为false
}

👆选择单个商品

checkShop(item){//与单选商品类似
    !item.checked ? this._shopTrue(item) : this._shopFalse(item)
},
_shopTrue(item){//遍历商店每一个商品,状态为false的改变为true,又在_checkTrue()方法中将商店状态改为true
    item.productList.forEach((pro)=>{
        pro.isChecked === false ? this._checkTrue(item,pro) : ''
    })
},
_shopFalse(item){
    item.productList.forEach((pro)=>{//同上
        pro.isChecked === true ? this._checkFalse(item,pro) : ''
    })
}

👆选择整个商店的商品

checkAll(){//方法内调用方法
    this.isCheckAll = !this.isCheckAll
    this.isCheckAll?
        this.carts.forEach((item)=>{this._shopTrue(item)}):
        this.carts.forEach((item)=>{this._shopFalse(item)})
},
_totalPeice(){//每次调用此方法,将初始值为0,遍历价格并累加
    this.allPrice = 0
    this.carts.forEach(item=>{
        let products = item.productList
        products.forEach(pros=>{
            if(pros.isChecked){
                this.allPrice += pros.price*pros.count
            }
        })
    })
},
_totalCount(){//同上
    this.allCount = 0
    this.carts.forEach(item=>{
        this.allCount += item.checkedCount
    })
}

👆选择全部商店的商品,已经计算总价和总数量的函数

watch:{//深度监听所有数据,每次改变重新计算总价和总数
    carts:{
        deep:true,
        handler(val,oldval){
            this._totalPeice()
            this._totalCount()
        }
    }
}

👆使用watch方法并将deep属性设置为true,对carts的数据深度watcher,改变时重新统计总价,总数量


  • 大量运用的三元运算,只要看懂,就不觉得复杂了
  • 通过函数调用函数,最底层的函数来实现状态的改变,逻辑最为清晰
  • 在实际调用接口中,可能没有checked这个状态值,使用vue.set来对数据设置状态值
  • 只是对购物车实现的demo,没有做添加,删除等功能,后期完善
  • 主要逻辑来自于羽叶千寻,加上一点自己的优化

相关文章

网友评论

      本文标题:[vue]仿淘宝app购物车实现

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