Vue购物车实战

最近学习在学由梁灏著作的Vue.js实战,其中有一章讲述如何用Vue开发购物车的章节,即课后练习,以下书中的开发过程即本人的课后练习,希望能对你学习Vue有所帮助。

购物车的基本功能

通过增加或减少商品的数量来控制商品总价

css样式

[v-cloak]{
	display: none;
}
table {
	border: :1px solid #e9e9e9;
	border-collapse:collapse ;
	border-spacing:0 ;
	empty-cells: show;
}
th{
	background: #f7f7f7;
	color: #5c6b77;
	font-weight: 600;
	white-space: nowrap;
	border: :1px solid #eee;
}
th,td{
	padding: 8px 16px;
	text-align: center;
	border: 1px solid #eee;
}

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

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../../../js/vue.js"></script>
		<link href="cart.css" rel="stylesheet" type="text/css" />
	</head>
	<body>
		<div id="app" v-cloak>
			<template v-if="list.length">
				<table>
					<thead>
						<tr>
							<th><input type="radio" :checked="checkAll" @click="handleSelectAll"></input></th>
							<th>商品名称</th>
							<th>商品单价</th>
							<th>购买数量</th>
							<th>操作</th>
						</tr>
					</thead>
					<tbody>
						<tr v-for="(item,index) in list">
							<td><input type="radio" :checked="item.checked" @click="handleSelect(index)"></input>
							</td>
							<td>{{item.name}}</td>
							<td>{{item.price}}</td>
							<td>
							<button @click="handleReduce(index)" :disabled="item.count===1">-</button>
							{{item.count}}
							<button @click="handleAdd(index)" :disabled="item.count===9">+</button>
							</td>
							<td>
							<button @click="handlerRemove(index)">移除</button>
							</td>
						</tr>
					</tbody>
				</table>
				<div>总价¥{{totalPrice}}</div>
			</template>
			<div v-else>购物车为空</div>
		</div>
		<script src="cart.js"></script>
	</body>
</html>

var dataList = [{
	id: 1,
	name: "iphone 7",
	price: 5000,
	count: 1,
	checked: false
}, {
	id: 2,
	name: "iPad Pro",
	price: 5888,
	count: 1,
	checked: false
},{
	id: 3,
	name: "MacBook Pro",
	price: 21488,
	count: 1,
	checked: false
}]
var vm = new Vue({
	el: "#app",
	data: {
		list: dataList,
		checkAll: false
	},
	computed: {
		totalPrice: {
			get: function() {
				var total = 0;
				for (var i = 0; i < this.list.length; i++) {
					var item = this.list[i];
					if (item.checked) {
						total += item.price * item.count;
					}
				}
				return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');
			}
		},
	},
	methods: {
		handleReduce: function(index) {
			if (this.list[index].count === 1) return;
			this.list[index].count--;
		},
		handleAdd: function(index) {
			this.list[index].count++;
		},
		handlerRemove: function(index) {
			this.list.splice(index, 1);
		},
		handleSelect: function(index) {
			var item = this.list[index],
				thisCheck = item.checked;
			item.checked = !thisCheck;
			if (thisCheck) {
				this.checkAll = false;
			} else {
				var checkList = this.list.find(function(item) {
					return item.checked === false;
				});
				if (typeof checkList=="undefined") {
					this.checkAll = true;
				}
			}
		},
		handleSelectAll: function() {
			var checkAll = !this.checkAll;
			for (var item of this.list) {
				item.checked = checkAll;
			}
			this.checkAll = checkAll;
		}

}
})

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

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<link href="cart.css" rel="stylesheet" type="text/css" />
		<script src="../../../js/vue.js"></script>
	</head>
	<body>
		<div id="app" v-cloak>
			<template v-if="list.length">
			<table>
				<thead>
					<tr>
						<th>商品分类</th>
						<th><input type="radio" :checked="checkAll" @click="handleSelectAll">全选</input></th>
						<th>商品名称</th>
						<th>商品单价</th>
						<th>购买数量</th>
						<th>操作</th>
					</tr>
				</thead>
				<template v-for="(item,index) in list">
					<tbody>
						<tr>
							<td colspan="6" style="text-align: left;">{{ item[0] }}</td>
						</tr>
						<tr v-for="(item1,index2) in item[1]">
							<td></td>
							<td><input type="radio" :checked="item1.checked" @click="handlerSelect(index,index2)"></input></td>
							<td>{{item1.name}}</td>
							<td>{{item1.price}}</td>
							<td><button @click="handleReduce(index,index2)" :disabled="item1.count===1">-</button>
							{{item1.count}}
							<button @click="handleAdd(index,index2)">+</button>
							</td>
							<td><button @click="handlerRemove(index,index2)">移除</button></td>
						</tr>
					</tbody>
			    </template>
			</table>
			<div>{{totalPrice}}</div>
			</template>
		    <div v-else>购物车为空</div>
		</div>
			<script src="cart2.js"></script>
	</body>
</html>

var dataList = [
	[
		"电子产品",
		[{
			id: 1,
			name: "iphone 7",
			price: 5000,
			count: 1,
			checked: false
		}, {
			id: 2,
			name: "iPad Pro",
			price: 5888,
			count: 1,
			checked: false
		}, {
			id: 3,
			name: "MacBook Pro",
			price: 21488,
			count: 1,
			checked: false
		}]
	],
	[
		"生活用品",
		[{
			id: 1,
			name: "牙膏",
			price: 16,
			count: 1,
			checked: false
		}, {
			id: 2,
			name: "脸盆",
			price: 10,
			count: 1,
			checked: false
		}, {
			id: 3,
			name: "拖把",
			price: 70,
			count: 1,
			checked: false
		}]
	],
	[
		"果蔬",
		[{
			id: 1,
			name: "苹果",
			price: 1,
			count: 1,
			checked: false
		}, {
			id: 2,
			name: "香蕉",
			price: 0.8,
			count: 1,
			checked: false
		}, {
			id: 3,
			name: "橘子",
			price: 0.6,
			count: 1,
			checked: false
		}]
	]
]
var vm = new Vue({
	el: "#app",
	data: {
		list: dataList,
		checkAll: false,
	},
	methods: {
		handleAdd: function(index, index2) {
			this.list[index][1][index2].count++;
		},
		handleReduce: function(index, index2) {
			if (this.list[index][1][index2].count == 1) return;
			this.list[index][1][index2].count--;
		},
		handlerRemove: function(index, index2) {
			var _list = this.list[index],
				_list_01 = _list[1];
			_list_01.splice(index2, 1);
			if (_list_01.length == 0) {
				this.list.splice(index, 1);
			}
		},
		handlerSelect: function(index, index2) {
			var _list = this.list[index],
				_list_01 = _list[1][index2],
				_checked = _list_01.checked;
			_list_01.checked = !_checked;
			if (_checked) {
				this.checkAll = false;
			} else {
				var checkList = this.list.find(function(item) {
					return item[1].find(function(item_01) {
						return item_01.checked === false;
					})
				});
				if (typeof checkList == "undefined") {
					this.checkAll = true;
				}
			}
		},
		handleSelectAll: function() {
			var checkAll = !this.checkAll;
			for (var item of this.list) {
				for(var item_01 of item[1]){
					item_01.checked=checkAll;
				}
			}
			this.checkAll = checkAll;
		}
	},
	computed: {
		totalPrice: function() {
			var total = 0;
			for (var item of this.list) {
				var list_01 = item[1];
				for (var item_01 of list_01) {
					if (item_01.checked) {
						total += item_01.price * item_01.count;
					}
				}
			}
			return total.toFixed(2).toString().replace(/\B(?=(\d{3})+$)/g, ',');;
		}
	}
})

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值