《vue.js实战》利用计算属性、指令等知识开发购物车练习2

购物车需要展示一个已加入购物车的商品列表,包含商品名称、商品单价、购买数量和操作等信息,还需要实时显示购买总价。其中购买数量可以增加或减少,每类商品还可以从购物车中移除。

练习1:在当前示例基础上扩展商品列表,新增一项是否选中该商品的功能,总价变为只计算选中商品的总价,同时提供一个全选的按钮。

练习2:将商品列表list改为一个二维数组来实现商品的分类,比如可分为“电子产品” “生活用品” 和“果蔬”,同类商品聚合在一起。提示,你可能会用到两次v-for。
 


练习2 html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div id="app" v-cloak>
        <template v-if="list.length">
            <table>
                <thead>
                    <tr>
                        <th></th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>购买数量</th>
                        <th>操作</th>
                        <th>
                            <!-- <button @click="selectAll">全选</button> -->
                            全选<input type="checkbox" @click="dealSelectAll" :checked="isSelectAll">
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <template v-for="(item,index) in list">
                        <tr>
                            <td colspan="6" class="shopClass">{{ item.title }}
                                <input type="checkbox" @click="goodsSelectAll(index)" :checked="item.isSelect">
                            </td>
                        </tr>
                        <tr v-for="(subItem, subIndex) in item.list">
                            <td>{{ subIndex + 1 }}</td>
                            <td>{{ subItem.name }}</td>
                            <td>{{ subItem.price }}</td>
                            <td>
                                <button 
                                    @click="handleReduce(index,subIndex)" 
                                    :disabled="subItem.count === 1">-</button>
                                {{ subItem.count }}
                                <button @click="handleAdd(index,subIndex)">+</button>
                            </td>
                            <td>
                                <button @click="handleRemove(index,subIndex)">移除</button>
                            </td>
                            <td>
                                <input type="checkbox" @click="dealSelect(index,subIndex)" :checked="subItem.isSelect">
                            </td>
                        </tr>
                    </template>
                </tbody>
            </table>
            <div>总价:¥ {{ totalPrice }}</div>
        </template>
        <div v-else>购物车为空</div>
    </div>
    <!-- vue引导一定要再js脚本前,不然会报错 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./index.js"></script>
</body>
</html>

练习2 js:

var app = new Vue({
    el: '#app',
    data: {
        isSelectAll: false,
        list: [
            {
                isSelect: false,
                title: '电子产品',
                list: [
                    {
                        id: 1001,
                        name: 'iphone7',
                        price: 6188,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 1002,
                        name: 'ipad Pro',
                        price: 5888,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 1003,
                        name: 'MacBook Pro',
                        price: 21488,
                        count: 1,
                        isSelect: false
                    }
                ]
            },
            { 
                title: '生活用品', 
                isSelect: false,
                list: [
                    {
                        id: 2001,
                        name: '洗面奶',
                        price: 68,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 2002,
                        name: '沐浴露',
                        price: 48,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 2003,
                        name: '香皂',
                        price: 18,
                        count: 1,
                        isSelect: false
                    }
                ]
            },
            { 
                isSelect: false,
                title: '果蔬',                 
                list: [
                    {
                        id: 3001,
                        name: 'apple',
                        price: 8,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 3002,
                        name: 'banana',
                        price: 3,
                        count: 2,
                        isSelect: false
                    },
                    {
                        id: 3003,
                        name: 'tomato',
                        price: 5,
                        count: 1,
                        isSelect: false
                    }
                ]
            }
        ]
    },
    computed: {
        totalPrice: function(){
            var total = 0;
            for(shop of this.list){
                for(goods of shop.list){
                    if(goods.isSelect){
                        total += goods.price * goods.count;
                    }
                }
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');//转换为带有千位分隔符的数字
        }
    },
    methods: {
        handleReduce: function(index,subIndex){
            var shop = this.list[index];
            if(shop.list[subIndex].count === 1) return;
            shop.list[subIndex].count--;
        },
        handleAdd: function(index,subIndex){
            var shop = this.list[index];
            shop.list[subIndex].count++;
        },
        handleRemove: function(index,subIndex){
            var shop = this.list[index];
            shop.list.splice(subIndex,1);
        },
        goodsSelectAll: function(index){
            var _this = this;
            var shop = _this.list[index];
            shop.isSelect = !shop.isSelect;
            for(goods of shop.list){
                goods.isSelect = shop.isSelect;
            }

            var isSelectAllShop = true;
				for(shop of _this.list){
					if(shop.isSelect==false){
						isSelectAllShop=false;
					}
				}

				if(isSelectAllShop){
					_this.isSelectAll=true;
				}else{
					_this.isSelectAll=false;
				}
        },
        dealSelect: function(index,subIndex){
            var _this = this;
            var shop = _this.list[index];
            // shop.isSelect =  !shop.isSelect;
            var goods = shop.list[subIndex];
            goods.isSelect = !goods.isSelect;

            //判断所有商品是否被选中
			var isSelectAllGoods = true;
			for(goods of shop.list){
				if(goods.isSelect==false){
					isSelectAllGoods=false;
				}
			}
			if(isSelectAllGoods){
				shop.isSelect=true;
			}else{
				shop.isSelect=false;
			}

			//判断所有商铺是否被选中
			var isSelectAllShop = true;
			for(shop of _this.list){
				if(shop.isSelect === false){
					isSelectAllShop = false;
				}
			}
				
			if(isSelectAllShop){
				_this.isSelectAll=true;
			}else{
				_this.isSelectAll=false;
			}
        },
        dealSelectAll: function(){
            var _this = this;
            _this.isSelectAll = !_this.isSelectAll;
            for(shop of _this.list){
                shop.isSelect = _this.isSelectAll;
                for(goods of shop.list){
                    goods.isSelect = _this.isSelectAll;
                }
            }
        }
    }
})

练习2 css:

var app = new Vue({
    el: '#app',
    data: {
        isSelectAll: false,
        list: [
            {
                isSelect: false,
                title: '电子产品',
                list: [
                    {
                        id: 1001,
                        name: 'iphone7',
                        price: 6188,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 1002,
                        name: 'ipad Pro',
                        price: 5888,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 1003,
                        name: 'MacBook Pro',
                        price: 21488,
                        count: 1,
                        isSelect: false
                    }
                ]
            },
            { 
                title: '生活用品', 
                isSelect: false,
                list: [
                    {
                        id: 2001,
                        name: '洗面奶',
                        price: 68,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 2002,
                        name: '沐浴露',
                        price: 48,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 2003,
                        name: '香皂',
                        price: 18,
                        count: 1,
                        isSelect: false
                    }
                ]
            },
            { 
                isSelect: false,
                title: '果蔬',                 
                list: [
                    {
                        id: 3001,
                        name: 'apple',
                        price: 8,
                        count: 1,
                        isSelect: false
                    },
                    {
                        id: 3002,
                        name: 'banana',
                        price: 3,
                        count: 2,
                        isSelect: false
                    },
                    {
                        id: 3003,
                        name: 'tomato',
                        price: 5,
                        count: 1,
                        isSelect: false
                    }
                ]
            }
        ]
    },
    computed: {
        totalPrice: function(){
            var total = 0;
            for(shop of this.list){
                for(goods of shop.list){
                    if(goods.isSelect){
                        total += goods.price * goods.count;
                    }
                }
            }
            return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');//转换为带有千位分隔符的数字
        }
    },
    methods: {
        handleReduce: function(index,subIndex){
            var shop = this.list[index];
            if(shop.list[subIndex].count === 1) return;
            shop.list[subIndex].count--;
        },
        handleAdd: function(index,subIndex){
            var shop = this.list[index];
            shop.list[subIndex].count++;
        },
        handleRemove: function(index,subIndex){
            var shop = this.list[index];
            shop.list.splice(subIndex,1);
        },
        goodsSelectAll: function(index){
            var _this = this;
            var shop = _this.list[index];
            shop.isSelect = !shop.isSelect;
            for(goods of shop.list){
                goods.isSelect = shop.isSelect;
            }

            var isSelectAllShop = true;
				for(shop of _this.list){
					if(shop.isSelect==false){
						isSelectAllShop=false;
					}
				}

				if(isSelectAllShop){
					_this.isSelectAll=true;
				}else{
					_this.isSelectAll=false;
				}
        },
        dealSelect: function(index,subIndex){
            var _this = this;
            var shop = _this.list[index];
            // shop.isSelect =  !shop.isSelect;
            var goods = shop.list[subIndex];
            goods.isSelect = !goods.isSelect;

            //判断所有商品是否被选中
			var isSelectAllGoods = true;
			for(goods of shop.list){
				if(goods.isSelect==false){
					isSelectAllGoods=false;
				}
			}
			if(isSelectAllGoods){
				shop.isSelect=true;
			}else{
				shop.isSelect=false;
			}

			//判断所有商铺是否被选中
			var isSelectAllShop = true;
			for(shop of _this.list){
				if(shop.isSelect === false){
					isSelectAllShop = false;
				}
			}
				
			if(isSelectAllShop){
				_this.isSelectAll=true;
			}else{
				_this.isSelectAll=false;
			}
        },
        dealSelectAll: function(){
            var _this = this;
            _this.isSelectAll = !_this.isSelectAll;
            for(shop of _this.list){
                shop.isSelect = _this.isSelectAll;
                for(goods of shop.list){
                    goods.isSelect = _this.isSelectAll;
                }
            }
        }
    }
})

效果截图:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值