好看的网页千篇一律,有趣的代码万里挑一。
今天看看如何用Vue做一个购物车。
head
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width
, initial-scale=1.0">
<title>购物车</title>
<style>
img {
height: 100px;
}
.shu {
width: 30px;
text-align: center;
}
.buy {
width: 150px;
}
td,
th {
padding: 5px;
text-align: center;
align-items: center;
}
.total {
line-height: 60px;
height: 60px;
display: block;
font-size: large;
font-weight: bolder;
margin-right: 20px;
}
</style>
</head>
body
<body>
<div id="app">
<!-- 如果数组中有数据,显示购物车 -->
<table v-if="goodses.length>0">
<tr>
<th><input type="checkbox" v-model="isckAll">全选</th>
<th>商品名称</th>
<th>商品图片</th>
<th>商品单价</th>
<th class='buy'>购买数量</th>
<th>小计</th>
<th>操作</th>
</tr>
<tr v-for="(item,index) in goodses" :key="item.id">
<td><input type="checkbox" v-model="item.isck"></td>
<td>{{item.name}}</td>
<td>
<img :src="item.img">
</td>
<td>
¥{{item.price | toFixed2}}
</td>
<td>
<!-- :disabled绑定的值为true,按钮禁用 -->
<button @click="item.count--" :disabled="item.count===1">-</button>
<input class='shu' readonly type="text" :value="item.count">
<button @click="item.count++" :disabled="item.count===10">+</button>
</td>
<td>¥{{item.price*item.count | toFixed2}}</td>
<td>
<button @click="delGoods(index)">删除</button>
</td>
</tr>
<tr>
<td colspan="7" class="totalPrice">
<span class='total'>总计:¥{{totalPrice | toFixed2}}</span>
<!-- 过滤器可以链式调用 -->
<span style="color: red;">美元:${{totalPrice | toUS | toFixed2}}</span>
</td>
</tr>
</table>
<!-- 否则显示下面的div -->
<div class="empty" v-else>
您的购物车空空如也
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.config.productionTip = false
new Vue({
el: "#app",
// 数据
data: {
// 商品数组
goodses: [{
// 商品编号
id: '1001',
// 商品名称
name: '小米手机',
// 商品图片
img: 'https://img.alicdn.com/bao/uploaded/i3/2279837698/O1CN01gkdsUP26jjYlI8HCS_!!2279837698.jpg',
// 商品单价
price: 1999,
// 购买数量
count: 3,
// 是否选中
isck: false
},
{
id: '1002',
name: '西门子冰箱',
img: 'https://img.alicdn.com/bao/uploaded/i4/2347095319/O1CN01xhxce31pA9MmYjHPc_!!2347095319.jpg',
price: 3999,
count: 2,
isck: true
},
{
id: '1003',
name: '索尼电视',
img: 'https://img.alicdn.com/bao/uploaded/i1/782731205/O1CN01o18KOx1KlvvaEIosx_!!0-item_pic.jpg',
price: 4999,
count: 1,
isck: true
},
{
id: '1004',
name: '联想电脑',
img: 'https://img.alicdn.com/bao/uploaded/i2/459462135/O1CN01yN7bD91RdsIyoddVW_!!459462135.jpg',
price: 5999,
count: 4,
isck: false
}
]
},
// 方法
methods: {
delGoods(index) {
if (confirm('是否确定删除?')) {
this.goodses.splice(index, 1)
}
}
},
// 计算属性
computed: {
// 表示是否全选
isckAll: {
// 返回结果
get() {
// 商品数组中所有的商品的状态为true时,返回true
return this.goodses.length > 0 && this.goodses.every(g => g.isck)
},
// 修改结果
set(val) {
// 循环所有的商品,设置所有商品的状态为最新的全选状态
this.goodses.forEach(g => {
g.isck = val
});
}
},
// 表示总价
totalPrice() {
/* let total = 0
for(let i=0;i<this.goodses.length;i++){
if(this.goodses[i].isck){
total += this.goodses[i].count * this.goodses[i].price
}
}
return total */
let total = 0
this.goodses.forEach(g => {
if (g.isck) {
total += g.price * g.count
}
})
return total
/* return this.goodses.filter(g=>g.isck).map(g=>g.price*g.count).reduce((c,g)=>{
return c + g
},0) */
}
},
// 过滤器
filters: {
// 数字保留两位小数
toFixed2(val) {
return val.toFixed(2)
},
// 转美金的方法
toUS(val) {
return val / 6.444
}
},
// 监听器
watch: {
// 监听totalPrice计算属性的值的变化
totalPrice(val) {
if (val > 100000) {
alert('您确定消费的起吗?请理性消费!')
}
}
}
})
</script>
</body>