vue.js入门之简单购物车

准备工作

环境

这里我们使用Bootstrap来简单的布局,并引入vue.js核心文件:

<link rel="stylesheet" type="text/css" href="../../Bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css"/>
<script src="../../jquery_qqchat/js/jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script>
<script src="../../Bootstrap/bootstrap-3.3.7-dist/js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>

注:Bootstrap引入顺序,先引入Bootstrap核心css文件,由于Bootstrap依赖于jQuery,因此,在引入Bootstrap核心js文件时,需先引入jQuery核心文件。

手动初始化数据

模拟一个购物车,我们需要一些订单数据,我们可以手动定义一个json数组来进行模拟:

let vue=new Vue({
			el:"#app",
			data:{
				goodsArr:[
					{id:0,name:"小米10",img:"img/5.png",price:4000,num:1},
					{id:1,name:"Redmi K30",img:"img/8.png",price:1700,num:1},
					{id:2,name:"Redmi K30 5G",img:"img/7.png",price:2000,num:1},
					{id:3,name:"小米CC9 Pro",img:"img/2.png",price:2600,num:1},
					{id:4,name:"Redmi 8",img:"img/1.png",price:700,num:1}
					],
			}
});

计算属性

需要计算购物车中的总金额,我们可以在methods里面写方法,也可以在computed里面写属性,两者的不同之处在于:所谓计算属性就可以看作是一个属性,使用时直接写属性名称,而方法在使用时,需要写的是:方法名()

computed:{
		sum2:function(){
				let money=0;
					for(let item of this.goodsArr){
						money+=item.price*item.num;
					}
					return money;
				}
			},

方法

那么说到方法,我们写个例子吧,比如我们需要在每一条记录上要计算出小计,即商品的单价*数量,可以写一个方法。此外,通常来说,购物车中也可以移除一条订单,因此我们也可以定义一个移除的方法,当点击移除按钮时,需要传入一个商品的id,用于标识用户要移除的是哪一个商品,然后根据商品的id来进行删除。

methods:{
				sum1(price,num){
					return price*num;
				},
				remove(id){
					if(confirm("确定要移除该商品吗?")){
						for(let i=0;i<this.goodsArr.length;i++){
							if(id==this.goodsArr[i].id){
								this.goodsArr.splice(i,1);
							}
						}
					}
				}
			}

使用表格布局

<div id="app">
			<div class="container">
				<div class="table-responsive">
					<table class="table table-hover " border="0" cellspacing="0" cellpadding="0">
						<thead align="center">
							<th>序号</th>
							<th>商品名称</th>
							<th>图片</th>
							<th>单价(元)</th>
							<th>总价(元)</th>
							<th>数量</th>
							<th>操作</th>
						</thead>
						<tr v-for="(good,index) in goodsArr">
							<td>{{index+1}}</td>
							<td>{{good.name}}</td>
							<td><img :src="good.img" style="width: 70px;height: 70px;"></td>
							<td>{{good.price}}</td>
							<td>
								{{sum1(good.price,good.num)}}
							</td>
							<td>
								<div class="input-group">
									<button :disabled="good.num<=1" class="btn-info input-group-addon" @click="good.num--">-</button>
									<input type="text" :value="good.num" size="2" readonly style="border-width:0px;background:#F5F5F5;width:25px;height: 28px;" />
									<button :disabled="good.num>=10" class="btn-info input-group-addon" @click="good.num++">+</button>
								</div>
							</td>
							<td><a class="btn btn-danger" href="#" @click.prevent="remove(good.id)">移除</a></td>
						</tr>
						<tr align="center">
							<td colspan="7">合计:{{sum2}} 元</td>
						</tr>
					</table>
				</div>
			</div>
		</div>
	</body>

注:我们自定义这样一个需求,每件商品的购买数量不得超过10,最低的购买数量不得少于1,我们可以使用 :disabled 来绑定,当数量大于10时,禁用按钮,当数量小于1时,也禁用按钮。此外,我们可以看到,移除我们使用的是一个超链接,我们只是使用了boostrap的样式看起来像按钮,但并非是一个button,那么,就会存在这样一个问题:当我们点击了之后,如果有连接地址,其实是会跳转的,我们事宜使用 @click.prevent来阻止其跳转。

效果图如下:
在这里插入图片描述

优化:在显示金额的地方,我们希望显示的格式为金额,如4000,应显示为:¥4000.00,我们可以手动写一个方法,只需在显示的地方调用此方法即可,具体如下:

showMoney(money){
	return "¥"+money.toFixed(2);//保留数值的2位小数点
}

可以看到这个方法非常第简单。

优化功能

  • 需求一:实现批量删除功能
  • 需求二:清空购物车

批量删除

思路:我们可以在操作列添加一个复选框,在表格的底部添加一个批量删除按钮,当点击了批量删除按钮时,按钮的名称变为取消,在旁边新增一个确定按钮,并且在把表头的操作改为全选,把移除按钮隐藏,复选框显示。当点击确定按钮时,需要把勾选的对应的商品删除。

  1. 定义变量标识,用于判断是显示移除按钮还是显示复选框
isBatchDel:false,
btnValue:"批量删除"

2.在相应的标签上使用v-show指令

<label v-show="isBatchDel">全选<input type="checkbox"  /></label>
<span v-show="!isBatchDel">操作</span> 
<input v-show="isBatchDel" type="checkbox" name="" value="" />
<a v-show="!isBatchDel" class="btn btn-danger" href="#" @click.prevent="remove(good.id)">移除</a>
<button class="btn btn-danger" @click="batchDelClick()">{{btnValue}}</button>
<button v-show="isBatchDel" class="btn btn-danger">确定</button>

3.编写方法,改变isBatchDel和btnValue的值

batchDelClick(){
	if(this.isBatchDel){
		this.isBatchDel=false;
		this.btnValue="批量删除";
	}else{
		this.isBatchDel=true;
		this.btnValue="取消";
    }
}

使用如上代码,我们就可以实现在移除和批量删除之间进行切换。
以上只是实现了一个界面的交互,并未实现功能,如当点击全选按钮时,下面所有的商品都应该被勾选下面继续:

  • 定义标识变量
isCheckedAll:false,//是否勾选了全选
delArr:[]//批量删除的商品id
  • 在checkbox上绑定v-model指令
<input v-show="isBatchDel" type="checkbox" :value="good.id" v-model="delArr" />
<label v-show="isBatchDel">全选<input type="checkbox" v-model="isCheckedAll" /></label>

注:如果是一个独立的复选框,选中后v-model得到的值是true,反之为false;如果是一个组的复选框 ,v-model=“数组” ,就会把选中的这个复选框的value值放入数组中,如果取消选中,会自动删除对应的value值。

  • 实现全选/全不选功能
 quanxuan(){
	if(!this.isCheckedAll){//勾选了全选
		 //勾选所有商品---把所有的商品id放入都delArr中
		for(let item of this.goodsArr){
			 this.delArr.push(item.id);
		}
	}else{//取消了全选
		//把delArr置空即可
		this.delArr=[];
	}
}
  • 批量删除
<button v-show="isBatchDel" class="btn btn-danger" @click="batchDel()">确定</button>
//批量删除
batchDel(){
	//遍历要删除的列表
	for(let id of this.delArr){
		//遍历所有的商品列表
		for(let i in this.goodsArr){
			//进行匹配,匹配成功后删除
			if(id==this.goodsArr[i].id){
				this.goodsArr.splice(i,1);
				break;
			}
		}
	}
}

清空购物车

<button class="btn btn-danger" @click="goodsArr=[]">清空购物车</button>

总结

本文实现了一个非常基础的购物车模型,用vue.js实现,这也算是入门级别的,其实,由于本人也是刚接触vue,想通过写文章做笔记的形式来巩固所学知识,若文中存在错误,还请提出指教。更多的学习可以到vue的官网,查看官方文档对学习更有帮助哦。
下面对本文中的部分知识进行总结:

  • ES6 for循环语法
  1. for_in
    如:
for(let i in this.goodsArr){
	if(id==this.goodsArr[i].id){
		this.goodsArr.splice(i,1);
	}
}

注:此方式的for循环为带下标的for循环

  1. for_of
for(let item of this.goodsArr){
		money+=item.price*item.num;
}

注:此方式的for循环相当于foreach循环

最后,附上本次练习的源码与效果图:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>购物车</title>
		<link rel="stylesheet" type="text/css" href="../../Bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css"/>
		<script src="../../jquery_qqchat/js/jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../Bootstrap/bootstrap-3.3.7-dist/js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<div class="container">
				<div v-show="goodsArr.length!=0" class="table-responsive">
					<table class="table table-hover " border="0" cellspacing="0" cellpadding="0">
						<thead align="center">
							<th>序号</th>
							<th>商品名称</th>
							<th>图片</th>
							<th>单价(元)</th>
							<th>总价(元)</th>
							<th>数量</th>
							<th>
								<label v-show="isBatchDel">全选<input type="checkbox" v-model="isCheckedAll" @click="quanxuan()" /></label>
								<span v-show="!isBatchDel">操作</span>
							</th>
						</thead>
						<tr v-for="(good,index) in goodsArr">
							<td>{{index+1}}</td>
							<td>{{good.name}}</td>
							<td><img :src="good.img" style="width: 70px;height: 70px;"></td>
							<td>{{showMoney(good.price)}}</td>
							<td>
								{{showMoney(sum1(good.price,good.num))}}
							</td>
							<td>
								<div class="input-group">
									<button :disabled="good.num<=1" class="btn-info input-group-addon" @click="good.num--">-</button>
									<input type="text" :value="good.num" size="2" readonly style="border-width:0px;background:#F5F5F5;width:25px;height: 28px;" />
									<button :disabled="good.num>=10" class="btn-info input-group-addon" @click="good.num++">+</button>
								</div>
							</td>
							<td>
								<input v-show="isBatchDel" type="checkbox" :value="good.id" v-model="delArr" />
								<a v-show="!isBatchDel" class="btn btn-danger" href="#" @click.prevent="remove(good.id)">移除</a>
							</td>
						</tr>
						<tr align="center">
							<td><button class="btn btn-danger" @click="goodsArr=[]">清空购物车</button></td>
							<td colspan="5">合计:{{showMoney(sum2)}} </td>
							<td align="left">
								<button class="btn btn-danger" @click="batchDelClick()">{{btnValue}}</button>
								<button v-show="isBatchDel" class="btn btn-danger" @click="batchDel()">确定</button>
							</td>
						</tr>
					</table>
				</div>
				<div v-show="goodsArr.length==0" id="">
					<h1 class="text-center">你的购物车空空如也,快去<a href="#">购物</a>吧!!!</h1>
				</div>
			</div>
		</div>
	</body>
	<script type="text/javascript">
		let vue=new Vue({
			el:"#app",
			data:{
				goodsArr:[
					{id:0,name:"小米10",img:"img/5.png",price:4000,num:1},
					{id:1,name:"Redmi K30",img:"img/8.png",price:1700,num:1},
					{id:2,name:"Redmi K30 5G",img:"img/7.png",price:2000,num:1},
					{id:3,name:"小米CC9 Pro",img:"img/2.png",price:2600,num:1},
					{id:4,name:"Redmi 8",img:"img/1.png",price:700,num:1}
					],
					isBatchDel:false,
					btnValue:"批量删除",
					isCheckedAll:false,//是否勾选了全选
					delArr:[]//批量删除的商品id
			},
			computed:{
				//合计
				sum2:function(){
					let money=0;
					for(let item of this.goodsArr){
						money+=item.price*item.num;
					}
					return money;
				}
			},
			methods:{
				//小计
				sum1(price,num){
					return price*num;
				},
				//单个移除
				remove(id){
					if(confirm("确定要移除该商品吗?")){
						for(let i in this.goodsArr){
							if(id==this.goodsArr[i].id){
								this.goodsArr.splice(i,1);
							}
						}
					}
				},
				showMoney(money){
					return "¥"+money.toFixed(2);//保留数值的2位小数点
				},
				//点击批量删除按钮
				batchDelClick(){
					if(this.isBatchDel){
						this.isBatchDel=false;
						this.btnValue="批量删除";
					}else{
						this.isBatchDel=true;
						this.btnValue="取消";
					}
				},
				//全选
				quanxuan(){
					if(!this.isCheckedAll){//勾选了全选
						//勾选所有商品---把所有的商品id放入都delArr中
						for(let item of this.goodsArr){
							this.delArr.push(item.id);
						}
					}else{//取消了全选
						//把delArr置空即可
						this.delArr=[];
					}
				},
				//批量删除
				batchDel(){
					//遍历要删除的列表
					for(let id of this.delArr){
						//遍历所有的商品列表
						for(let i in this.goodsArr){
							//进行匹配,匹配成功后删除
							if(id==this.goodsArr[i].id){
								this.goodsArr.splice(i,1);
								break;
							}
						}
					}
				}
			}
		});
	</script>
</html>

效果图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值