Vue实例结合Bootstrap-商城购物车效果

目前在学习Vue2.x 跟教程一起写的购物车实例,课程只讲获取数据和功能的实现,所以自己搭了一个简单界面,中间也遇到过问题,获取数据显示XML解析失败,后来发现我应该把项目放到服务器上运行,报错消失了。

下面是代码,供大家参考

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Vue界面使用本地数据</title>
	<link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css">
	<script type="text/javascript" src="jquery.js"></script>
	<script type="text/javascript" src="bootstrap/js/bootstrap.js"></script>
	<script type="text/javascript" src="Vue.js"></script>
	<script type="text/javascript" src="vue-resource.js"></script>
	<style>
		body{
			background: #e8e8e8;
		}
		@font-face{
			font-family: cart;
			src: url('fonts/icomoon.eot') format('embedded-opentype'),
		    url('fonts/icomoon.svg') format('svg'),
		    url('fonts/icomoon.ttf') format('truetype'),
		    url('fonts/icomoon.woff') format('woff');
		}
		#app{
			margin-top: 100px;
		}
		#app .container{
			background: #fff;
			padding: 20px 15px;
		}
		.cart{
			padding-left: 100px;
			border-bottom: 1px solid #eee;
			padding-bottom: 10px;
			position: relative;
		}
		.cart .check{
			width: 14px;
			height: 14px;
			position: absolute;
			top: 50%;
			margin-top: -7px;
			left: 0;
		}
		.cart .media-body{
			padding: 10px 200px 0 20px;
		}
		.cart .media-heading{
			color: #000;
			font-size: 20px;
		}
		.cart .media-body select{
			border: 1px solid #eee;
			background: #eee;
			/*隐藏select的下拉图标*/
			-moz-appearance: none;
			padding-right: 20px;
			line-height: 20px;
			font-size: 12px;
		}
		.cart .media-body .cart_select{
			position: relative;
			display: inline-block;
		}
		.cart .media-body .cart_select::after{
			content: "";
			position: absolute;
			top: 50%;
			margin-top: -3px;
			right: 3px;
			border-left: 6px solid transparent;
			border-top: 6px solid #666;
			border-right: 6px solid transparent;
		}
		.cart .media-body .data{
			margin-top: 20px;
			overflow: hidden;
			height: 24px;
			line-height: 20px;
		}
		.cart .totalPrice{
			float: right;
			width: 80px;
		}
		.cart .media-body .price,.cart .media-body .count{
			display: inline-block;
		}
		.cart .media-body .count{
			float: right;
			margin-right: 60px;
			border: 1px solid #ccc;
			padding: 0 2px;
			font-size: 12px;
			position: relative;
			font-weight: 500;
			height: 22px;
		}
		[class^="icon-"]{
			font-family: cart;
			font-style: normal;
		}
		.count input{
			display: inline-block;
			width: 20px;
			border: none;
			text-align: center;
			height: 20px;
			background: none;
		}
		.count i::before{
			position: absolute;
			padding: 0 3px;
			top: -1px;
			font-style: normal;
			cursor: pointer;
			border: 1px solid #ccc;
			background: #eee;
		}
		.count i.icon-minus::before{
			content: "\ea0b";
			left: -20px;
		}
		.count i.icon-plus::before{
			content: "\ea0a";
			right: -20px;
		}
		.userCart{
			margin-top: 20px;
		}
		.userCart-right{
			float: right;
			margin-right: 120px;
		}
		.userCart-right a{
			display: block;
			padding: 0 20px;
			line-height: 24px;
		}
		.userCart-left{
			display: inline-block;
		}
		.icon-bin{
			position: absolute;
			bottom: 24px;
			right: 122px;
		}
		.icon-bin i{
			font-style: normal;
			position: relative;
		}
		.icon-bin i::before{
			content: "\e9ac";
			position: absolute;
			top: 0;
			left: -10px;
			font-family: cart;
		}
	</style>
</head>
<body>

<div id="app">
	<div class="container">
		<div class="row">
			<div class="col-md-2">
				<ul class="nav nav-pills nav-stacked"> 
					<li role="presentation" class="active"><a href="javascript:;">购物车</a></li>
					<li role="presentation"><a href="javascript:;">个人中心</a></li>
				</ul>
			</div>
			<div class="col-md-10">
				<div class="media cart" v-for="(shop, index) in shopListArr">
					<div class="media-left">
						<input class="check" type="checkbox" :checked="shop.checked" @click="singerShopSelected(shop)">
						<a href="#">
							<img class="media-object" width="140" :src="shop.shopImage" :alt="shop.shopName">
						</a>
					</div>
					<div class="media-body">
						<a class="media-heading" href="javascript:;" v-text="shop.shopName"></a>
						<p v-text="shop.shopDetail"></p>
						<div class="cart_select">
							<select>
								<option value="绿木兰花">{{shop.shopStyle[0]}}</option>
								<option value="黄色绽放">{{shop.shopStyle[1]}}</option>
								<option value="水墨荷花">{{shop.shopStyle[2]}}</option>
							</select>
						</div>
						<div class="data">
							<span class="price">{{shop.shopPrice | moneyFormat(shop.shopPrice)}}</span>
							<div class="totalPrice">{{shop.shopNumber*shop.shopPrice | moneyFormat(shop.shopNumber*shop.shopPrice)}}</div>
							<div class="count">
								<i class="icon-minus" @click="singleShopPrice(shop, false)"></i>
								<!-- false是减 true是加 -->
								<input type="tel" value="" v-model="shop.shopNumber">
								<i class="icon-plus" @click="singleShopPrice(shop, true)"></i>
							</div>
						</div>
						<div class="icon-bin" data-toggle="modal" data-target="#myModal" @click="clickTrash(shop)">
							<i></i>
						</div>
					</div>
				</div>
				<div class="userCart">
					<input type="checkbox" :checked="isSelectedAll" @click="selectedAll(isSelectedAll)">全选
					<div class="userCart-left">
						合计:<span class="allShopPrice">{{totalPrice | moneyFormat(totalPrice)}}</span>
					</div>
					<div class="userCart-right">
						<a class="btn btn-primary" href="javascript:;">去结算</a>
					</div>
				</div>
			</div>
		</div>
	</div>
	<!-- 弹出面板 -->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
					<h4 class="modal-title" id="myModalLabel">删除商品</h4>
				</div>
	      		<div class="modal-body">
			       	您确定要删除商品?
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
					<button type="button" class="btn btn-primary" data-dismiss="modal" @click="delShop()">确定</button>
				</div>
			</div>
		</div>
	</div>
</div>






<script type="text/javascript">

	new Vue({
		el: "#app",
		data: {
			// 购物车中的数据
			shopListArr: [],
			// 是否全选
			isSelectedAll: false,
			// 所有商品的总价格
			totalPrice: 0,
			// 要删除的商品
			currentDelShop: {}
		},
		// 钩子函数 组件已经加载完毕 请求网络数据 业务处理
		mounted(){

			// 请求本地的数据
			this.getLocalData();

		},
		// 钩子选项 过滤
		filters: {
			// 格式化金钱
			moneyFormat(money){
				return "¥" + money.toFixed(2);   // 保留两位小数
			}
		},
		methods: {
			// 1. 请求本地的数据
			getLocalData(){
				
				this.$http.get('data/cart.json').then(response => {

					const res = response.body;
					if( res ){
						this.shopListArr = res.allShops.shopList;
					}

				}, response => {

					// 容错处理
					alert('请求数据失败!');

				});	
			},
			// 2. 单个商品数量
			singleShopPrice(shop, flag){
				if(flag){  //加
					shop.shopNumber += 1;
				}else{   //减
					if(shop.shopNumber <= 1){
						shop.shopNumber = 1;
						return;
					}
					shop.shopNumber -= 1;
				}
				// 计算总价
				this.getAllShopPrice();
			},
			// 3.选中所有的商品
			selectedAll(flag){
				// 3.1总控制
				this.isSelectedAll = !flag;
				
				// 3.2遍历所有的商品数据
				this.shopListArr.forEach((value, index)=>{   //箭头函数
					if(typeof value.checked === 'undefined'){
						this.$set(value, 'checked', !flag);    //为商品实例设置checked属性
					}else{
						value.checked = !flag;
					}
				});
				
				//3.3计算总价格
				this.getAllShopPrice();
			},
			// 4.计算商品的总价格
			getAllShopPrice(){
				let totalPrice = 0;
				// 4.1遍历所有的商品
				this.shopListArr.forEach((value,index)=>{
					// 判断商品是否被选中
					if(value.checked){
						totalPrice += value.shopPrice * value.shopNumber;
					}
				});
				this.totalPrice = totalPrice;
			},
			// 5.单个商品的选中和取消
			singerShopSelected(shop){
				// 5.1判断有没有这个属性
				if(typeof shop.checked === 'undefined'){
					this.$set(shop, 'checked', true);
				}else{
					shop.checked = !shop.checked;
				}
				
				// 5.2计算总价
				this.getAllShopPrice();
				
				// 5.3判断是否全选
				this.hasSelectedAll();
			},
			// 6.判断是否全选
			hasSelectedAll(){
				let flag = true;
				this.shopListArr.forEach((value, index)=>{
					if(!value.checked){   //只要有一个没被选中,就是false
						flag = false;
					}
				});
				this.isSelectedAll = flag;
			},
			// 7.点击垃圾筐
			clickTrash(shop){
				this.currentDelShop = shop;
			},
			// 8.删除商品
			delShop(){
				let index = this.shopListArr.indexOf(this.currentDelShop);
				this.shopListArr.splice(index,1);
				
				this.getAllShopPrice();
			}
		}

	});


</script>
</body>
</html>

上面是.jsp文件,直接复制可以用,但是得有Bootstrap、Vue.js、vue-resource.js、jQuery.js,注意引入顺序~~~

{
	"allShops": {
		"totalMoney": 0,
		"shopList": [
			{
				"shopId": "1001",
				"shopName": "女孩旗袍夏款",
				"shopPrice": 58,
				"shopNumber": 1,
				"shopImage": "img/03.jpg",
				"shopDetail": "中国风盘口短袖女宝1-8岁复古民族风儿童汉服连衣裙",
				"shopStyle": ["绿木兰花","黄色绽放","水墨荷花"]
			},
			{
				"shopId": "1002",
				"shopName": "斯拉夫酸奶威化",
				"shopPrice": 39.8,
				"shopNumber": 2,
				"shopImage": "img/01.jpg",
				"shopDetail": "斯拉夫酸奶威化1000g俄罗斯进口巧克力夹心饼干进口零食",
				"shopStyle": ["绿木兰花","黄色绽放","水墨荷花"]
			},
			{
				"shopId": "1003",
				"shopName": "美式实木台灯北欧",
				"shopPrice": 185.0,
				"shopNumber": 1,
				"shopImage": "img/02.jpg",
				"shopDetail": "美式实木台灯北欧卧室床头灯温馨客厅装饰浪漫结婚灯现代简约创意",
				"shopStyle": ["A款 送5瓦led","B款 送5瓦led","C款 送5瓦led"]
			}
		]
	}
}

上面是JSON数据,我用的本地数据

还有图片自己准备一下哈,哦对了,我用了字体图标

https://icomoon.io/app/#/select/font

这是图标下载地址

右下角点击下载哈~

欢迎大家评论,一起交流学习,一起进步

猜你喜欢

转载自blog.csdn.net/qq_42381297/article/details/82501885
今日推荐