<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name ="viewport" content ="width = device-width,initial-scale = 1.0,user-scalable = no"/>
<title>shopcart</title>
<link rel="stylesheet" type="text/css" href="static/css/iview.css">
<script type="text/javascript" src="static/js/vue.js"></script>
<script type="text/javascript" src="static/js/iview.min.js"></script>
<style>
* {
padding: 0;
margin: 0;
list-style: none;
}
header {
height: 42px;
width: 100%;
position: fixed;
top: 0;
left: 0;
background: #fff;
box-shadow: 0px 0px 20px rgba(0, 0, 0, .1);
font-size: 20px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
}
header span {
font-size: 14px;
font-weight: bold;
}
footer {
height: 42px;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
background: #fff;
box-shadow: 0px 0px 20px rgba(0, 0, 0, .1);
}
footer ul {
display: flex;
flex-direction: row;
justify-content: space-around;
}
footer ul li {
line-height: 42px;
text-align: center;
font-weight: bold;
font-size: 24px;
height: 42px;
}
footer ul li:nth-child(3) {
position: relative;
}
.num-badge {
position: absolute;
top: 0;
font-weight: normal;
display: block;
background: #ed3f14;
width: 20px;
height: 20px;
border-radius: 50%;
font-size: 9px;
right: -10px;
overflow: hidden;
line-height: 20px;
text-align: center;
color: #fff;
}
.container {
margin-top: 42px;
margin-bottom: 42px;
}
.goods-list {
padding: 8px;
}
.goods {
display: flex;
padding-top: 10px;
flex-direction: row;
justify-content: space-between;
padding-bottom: 10px;
position: relative;
}
.goods:after {
content: ' ';
position: absolute;
bottom: 0;
display: block;
width: 200%;
left: -50%;
height: 1px;
background: #ededed;
-webkit-transform:scale(0.5);
}
.goods img {
height: 64px;
width: 64px;
border-radius: 2px;
}
.goods-title {
font-weight: bolder;
font-size: 13px;
}
.goods-content {
display: flex;
flex-direction: column;
justify-content: space-around;
flex: 1;
margin-left: 10px;
}
.goods-desc {
font-size: 9px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width: 150px;
}
.goods-price {
color: red;
}
.cart-controller {
display: flex;
flex-direction: row;
align-items: center;
}
.cart-controller span{
margin-right: 5px;
}
.reduce,.add {
font-size: 18px;
color: #2d8cf0;
}
.goods-num {
width: 12px;
text-align: center;
}
.cart-bar {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 42px;
width: 100%;
background: #fff;
align-items: center;
padding: 5px;
position: fixed;
top: 0;
left: 0;
z-index: 11;
}
.pay-btn {
width: 70px;
}
.total-price {
text-align: center;
flex: 1;
font-size: 13px;
color: red;
}
.total-price span {
color: #222;
font-size: 18px;
font-weight: bolder;
}
.num-badge.gray {
background: #ccc;
}
.slide-fade-enter-active {
transition: all .1s ease;
}
.slide-fade-leave-active {
transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<header>
<Icon type="ios-list" style="margin-left:10px;"></Icon>
<span>{{pageHead}}</span>
<Icon type="ios-search" style="margin-right:10px;"></Icon>
</header>
<div class="container">
<ul class="goods-list">
<!-- css3 动画名称 -->
<transition name="slide-fade" v-for="(goods,index) in goodsList">
<li class="goods" v-if="goods.goods_num">
<img :src="goods.goods_thumb" alt="">
<div class="goods-content">
<p class="goods-title">{{goods.goods_name}}</p>
<p class="goods-desc">{{goods.goods_desc}}</p>
<p class="goods-price">¥{{goods.goods_price}}</p>
</div>
<div class="cart-controller">
<span class="reduce" @click="reduceGoods(index)">
<Icon type="minus-circled"></Icon>
</span>
<span class="goods-num">{{goods.goods_num}}</span>
<span class="add" @click="addGoods(index)">
<Icon type="plus-circled"></Icon>
</span>
</div>
</li>
</transition>
</ul>
<div class="cart-bar">
<div class="total-price">
<span>Total:</span> ¥{{totalPrice}}
</div>
<i-button type="success" class="pay-btn" @click="pay(totalPrice)">支付</i-button>
</div>
</div>
<Modal v-model="modal6" title="提示" @on-ok="ok" @on-cancel="cancel">
<p>总价:¥{{totalPrice}}</p>
</Modal>
<footer>
<ul>
<li>
<Icon type="ios-home"></Icon>
</li>
<li>
<Icon type="ios-chatbubble"></Icon>
</li>
<li>
<Icon type="ios-cart"></Icon>
<!-- 绑定样式,isGray为true时显示 -->
<span class="num-badge" v-bind:class="{gray:isGray}">{{goodsNum}}</span>
</li>
<li>
<Icon type="ios-person"></Icon>
</li>
</ul>
</footer>
</div>
<script>
new Vue({
el: '#app',
data: {
isGray: false,//默认false
modal6: false,
pageHead: "购物车",
goodsList: [
{
goods_name: "Coca Cola",
goods_desc: "可口可乐,made in America",
goods_price: "12",
goods_thumb: "static/images/cola.jpg",
goods_num: 6
},{
goods_name: "女装",
goods_desc: "夏日女装",
goods_price: "199",
goods_thumb: "static/images/clothfamale.jpg",
goods_num: 1
},{
goods_name: "macbook 13寸 经典版",
goods_desc: "macbook 13寸 经典版,限时打折",
goods_price: "6999",
goods_thumb: "static/images/mac.jpg",
goods_num: 1
},{
goods_name: "青芒果",
goods_desc: "深山青芒果",
goods_price: "6",
goods_thumb: "static/images/mongo.jpg",
goods_num: 5
},{
goods_name: "play station 4",
goods_desc: "索尼正品认证,限时赠送<<神秘海域4>>",
goods_price: "2666",
goods_thumb: "static/images/ps4.jpg",
goods_num: 1
},{
goods_name: "纯正米酒",
goods_desc: "哇哦~~",
goods_price: "99",
goods_thumb: "static/images/ricewine.jpg",
goods_num: 3
},
]
},
computed: {
totalPrice: function(){//计算总价
var total = 0;
this.goodsList.forEach(function(item,index){//循环商品列表,单价 x 数量,再加等
total += (item.goods_price - 0) * item.goods_num;
});
return total
},
goodsNum: function(){//加等每个商品种类的数量
var num = 0;
this.goodsList.forEach(function(item,index){
num += item.goods_num;
});
if(num == 0) {//如果商品总量为0时,this.isGray = true
this.isGray = true
}
return num
}
},
methods: {
//v-for="(goods,index) in goodsList" 通过这种方式获取index
addGoods: function(index){//@click(index),在商品列表数组中传入点击商品的index值,从而改变相应商品的数据
this.goodsList[index].goods_num ++ ;
},
reduceGoods: function(index){//@click(index),在商品列表数组中传入点击商品的index值,从而改变相应商品的数据
if(this.goodsList[index].goods_num <= 0) {//当商品数量小于或等于0时,利用vue的transition组件包裹单个goods li,做到动画消失
this.goodsList.splice(index,1);//也可以在goods----li 标签里利用v-if或者 v-bind:class="{your-animate-class:goods.goods_num}"方式
return //完全消失后在商品列表中移除该商品
}
this.goodsList[index].goods_num -- ;
},
pay: function(){
this.modal6 = true;//ivew 对话框组件,点击支付显示
},
ok: function(){//点击确定,关闭
this.modal6 = false;
this.$Message.success('支付成功');//iview 消息提示组件
},
cancel: function(){
this.modal6 = false;
this.$Message.success('取消支付');
}
}
})
/**
* 总结
* v-bind:class="{classname: variable<-->boolean}"
* @click="functionname()"绑定函数
* computed: 计算属性的运用; totalPrice,goodsNum
* splice(item,0,[]) => 0:增加item或者[]; 1: 删除item
* v-for="(item,index) in items" => item = self,index = self index
* v-if="variable" => true or false
* vue组件transition的运用 naem="animation-name" v-if状态的改变触发动画
* iview 组件Icon的使用,badge的使用(其中count属性不支持,count="{{ goodsNum }}"的形式 => 也许有解决方案,不行可以自行模拟)
* iview 组件this.$Message.success(msg)
* .info(msg)
* .error(msg)
* iview 组件<Modal v-modal="modalvalue" :loading="loading" @on-ok="ok" @on-cancel="cancel"></Modal> ==> 通过设置modalvalue的值来显隐modal对话框
* :loading => 是否在确定按钮上使用 loading 动画 title => 设置标题信息 @on-ok="ok" => 点击确定按钮回调函数 @on-cancel="cancel" => 点击取消按钮回调函数
*
* date: 2018-7-14 22:46
* author: Foresea
*
*
* ===================== 待续 =====================
*/
</script>
</body>
</html>
vue + iview 实现购物车功能
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...