第十四篇 表单控件 - 购物车页面

        上一篇内容 已经简单的介绍了表单控件以及表单控件的绑定,有登录界面输入的用户信息(userInfo)是否需要启动 "记住" 功能,"记住" 是一个记录登录状态,未勾选下次进入需要输入对应的用户信息才能登录进入,勾选后下次点击登录进入会调用本地存储的数据使用户简化操作,这一篇内容使用之前所学内容和表单控件来完成购物车界面当中的一些小功能; 

购物车

页面效果:  

         以上就是将要实现的一个页面效果以及相对应的功能,可以简单的对页面分析一下,同样这次也不会讲css样式的编写,大家可以分析讲的来完成这个内容;


基本思路

        将上面的页面分析之后,对页面进行编写,如在data中模拟几条商品数据,通过v-for循环渲染到前台页面,渲染完对应的商品之后,接下来是做事件处理,商品的一个增减器,但这里需要注意一个问题商品数量是不能够减到负数的,而增值是不能大于它所持有的库存,那么这里我们仅考虑这些,实际上是不止的,是需要做用户操作反馈,比如已经达到库存值需要提醒用户等的一些操作,加减可以用最简单的方式来完成,删除也是,可以同splice函数来处理,但这里需要对checkGroup的删除进行id的删除而不是索引值,同时可以在data中定义一个是否全选的值,默认值是false以及一个勾选集合checkGroup,在对应的每个商品选项勾选中添加一个v-model绑定勾选集合,同时绑定一个value值是当前的商品信息,再添加勾选监听,每次勾选的时候判断checkGroup中的长度跟我们购物车当中的数据长度是否相等,一样触发全选isAllChecked为true,不一样为false值;(这是通过之前所讲的内容提供的一个基本思路,可以让有看过之前的读者能够知道内容的渐进性!)

<div id="app">
	<header>
		<p>购物车</p>
	</header>
	<nav>
		<!-- 若无商品 -->
		<div class="nothing" v-if="goodsList.length===0">
			<p>暂无商品</p>
		</div>
		
		<!-- 若有商品 -->
		<template class="someing" v-else>
			<ul>
				<input type="checkbox" v-model="isAllChecked" @change="handleAllCheck"/>  全选
				<li v-for="(goods,index) in goodsList" :key="goods.id">
					<input type="checkbox" v-model="checkGroup" :value="goods" @change="checked"/>
					<div class="left"> 
						<!-- 图片 -->
						<img :src="goods.g_imgUrl" alt="">
					</div>
					<div class="right">
						<p>{{goods.shopname}} > </p> 
						<p>{{goods.g_name}}</p>
						<p>¥{{goods.g_price}}</p>
					</div>
					<div style="clear:both"></div>
					
					<!-- 增减器 -->
					<div class="Deletion">
						<button @click="goods.g_number++" :disabled="goods.g_number == goods.g_stock">+</button>
						<button type="text">{{goods.g_number}}</button>
						<button @click="goods.g_number--" :disabled="goods.g_number == 1">-</button>
					</div>
					
					<!-- 删除器 -->
					<div class="del">
						<button @click="del(index,goods.id)">x</button>
					</div>
					
				</li>
			</ul>
		</template>
	</nav>
	
	<footer>
		<p>总计:¥<span>{{sum()}}</span></p>
	</footer>
</div>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			checkGroup:[], // 勾选集合 
			isAllChecked:false, // 是否全选 
			goodsList:[ // 商品数据
				{
					id:1,
					shopname:'灵魂学者旗舰店2',
					g_name:'新款时尚小皮鞋',
					g_imgUrl:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.tjhcgroup.cn%2Fupload_files%2Ftk774191.jpg&refer=http%3A%2F%2Fwww.tjhcgroup.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666932261&t=e847f049741406c824952300da18ae8a',
					g_price:99.00,
					g_number:1,
					g_stock:10
				},
				{
					id:2,
					shopname:'灵魂学者旗舰店1',
					g_name:'韩版时尚女士手表',
					g_imgUrl:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fimgextra%2Fi2%2F2609976151%2FTB2tvvPk7qvpuFjSZFhXXaOgXXa_%21%212609976151.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666932063&t=a663cf024db0b336d152aaecb9ca5021',
					g_price:199.00,
					g_number:1,
					g_stock:10
				},
				{
					id:3,
					shopname:'灵魂学者旗舰店3',
					g_name:'YSL圣罗兰方管口红',
					g_imgUrl:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fci.xiaohongshu.com%2F77c1ab6c-5a76-4190-a2f4-7dc6ccbcc95d%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666932803&t=3fb95003eb0df69e098ba48c93914769',
					g_price:299.00,
					g_number:1,
					g_stock:10
				}
			],
		},
		methods:{
			
			// 删
			del(index,del_id){
				// console.log("index:"+index,"goods_id:"+del_id) // 测试
				// 过滤器 - 过滤掉要删除商品的id
				this.checkGroup = this.checkGroup.filter(goods=>goods.id!=del_id)
				
				this.goodsList.splice(index,1)
			},
			// 结算
			sum(){
				// 商品单价 * 数量 = 商品总价  总计:各商品总价
				var total = 0
				this.goodsList.forEach(goods=>{
					total += goods.g_price * goods.g_number
				})
				return total
			},
			
			// 全选/全不选
			// 监听isAllChecked的值,true全选,false不全选
			handleAllCheck(){
				// 监听是否勾选了 
				if(this.isAllChecked){ // 全选 ->  
					this.checkGroup = this.goodsList
				}else{
					this.checkGroup = []
				}
			},
			
			// 勾选时触发是否需要全选,通过两数组的长度判断
			checked(){
				if(this.checkGroup.length === this.goodsList.length){
					this.isAllChecked = true
				}else{
					this.isAllChecked = false 
				}
			}
			
		}
	})
</script>

问题 & 解决

问题1:有无数据状态呈现

        通过 v-if 和 v-else 来控制,当data中有数据时,即goodsList.length不等于0时,则将<div class="something">的内容显示在页面中,那么data中goodsList.length通过删除的时候goodsList.length等于0时,则将<div class ="nothing">的内容显示出来。

问题2:商品数量增减器

        在button做了@click的一个事件来让goods.g_number++或者goods.g_number--进行增加,当减到负数,通过:disable禁用掉,购买的数量减到0就不能减会被禁用掉,当增加的时候需要判断购买是否购买的数量是否超出商品已有的库存,超出无法继续增加。       

问题3:全选 / 勾选

        每一个商品的勾选是表单控件,通过v-model绑定checkGroup的勾选集合,以及将商品的信息绑定进去:value = "goods";当点击勾选的时候就会加到checkGroup的数组当中;同时为商品的每次勾选做监听,判断goodsList和checkGroup的长度是否相等,相等则视为全选,反之不全选。在data中定义一个isAllChecked,即是否全选,点击全选时,goodsList中的值就赋给checkGroup

 问题4:删除

        通过button的点击将对应的索引值(index)进行传过去,通过splice函数方法伤处掉goodsList中的商品数据,这个操作没有问题,但是删除的同时是需要删除对应在checkGroup中的商品数据,此时是不能够通过索引(index)的方式删除的;

前:

 后:

通过商品对应的id值,当我们点击删除的时候获取对应的商品的id,之后通过在checkGroup中将除去要被删除的其他id过滤出来

// 过滤器 - 过滤掉要删除商品的id
this.checkGroup = this.checkGroup.filter(goods=>goods.id!=del_id)

        以上就是这个购物车页面,用之前所讲的内容结合应用,后续将继续讲解新内容来进行修整案例!感谢大家的支持,如东西比较多,可以先理思路将页面编写下来,再进一步的的编写会比较好一些!


版权声明:本文为weixin_52203618原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。