效果展示图:
效果视图:
项目解构
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>cart</title>
</head>
<link rel="stylesheet" href="style.css">
<body>
<div id="app">
<div v-if="barbecue.length">
<!--如果页面有数据存在,则显示,无则。。-->
<table>
<thead>
<tr>
<th></th>
<th>口味必选</th>
<th>免费配选畅饮/杯</th>
<th>价格</th>
<th>份数</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in barbecue">
<td>{{item.id}}</td>
<td>
<img :src="item.image" alt="">
{{item.name}}
</td>
<td>
<select>
<option v-for="drink in softDrink">
{{drink}}
</option>
</select>
</td>
<td>{{item.price | showPrice}}</td>
<td>
<button @click="decrement(index)" :disabled="item.count <= 1">-</button>
{{item.count}}
<button @click="increment(index)">+</button>
</td>
<td><button @click="removeHandle(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2>总价格:{{totalPrice | showPrice}}</h2>
</div>
<h2 v-else>购物车为空!</h2>
</div>
<script src="main.js"></script>
</body>
</html>
style.css
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th {
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
img {
width: 50px;
height: 50px;
}
main.js
const app = new Vue({
el: "#app",
data() {
return {
barbecue: [
{
name: '烤鱿鱼串',
id: 1,
image: './images/img1.jpg',
price: 10,
count: 1
},
{
name: '烤羊肉串',
id: 2,
image: './images/img2.jpg',
price: 15,
count: 1
},
{
name: '烤韭菜',
id: 3,
image: './images/img3.jpg',
price: 3,
count: 1
},
{
name: '烤五花肉串',
id: 4,
image: './images/img4.jpg',
price: 13,
count: 1
},
],
softDrink: ['果汁橙', '芬达', '雪碧', '可乐', '健力宝', '王老吉', '加多宝', '燕京鲜啤', '纯生', '珠江零度', '菠萝啤']
}
},
methods: {
decrement(index) {
this.barbecue[index].count--
},
increment(index) {
this.barbecue[index].count++
},
removeHandle(index) {
this.barbecue.splice(index, 1)//移除对应的下标行
}
},
filters: {
showPrice(price) {
return '¥' + price.toFixed(2)
}
},
computed: {
totalPrice() {
// 1.一般遍历写法
let totalPrice = 0
for (let i = 0; i < this.barbecue.length; i++) {
totalPrice += this.barbecue[i].price * this.barbecue[i].count
}
return totalPrice
// //2.for in 写法
// let totalPrice = 0
// for (let i in this.barbecue) {
// totalPrice += this.barbecue[i].price * this.barbecue[i].count
// }
// return totalPrice
// //3.for of 写法
// let totalPrice = 0
// for (let item of this.barbecue) {
// totalPrice += item.price * item.count
// }
// return totalPrice
//4.高阶函数reduce写法:
// return this.barbecue.reduce(function(preValue, item){
// return preValue + item.price * item.count
// },0)
}
},
});
学习小笔记:
1.vue当中可以使用双重遍历,只要符合数组里面包裹着是对象的形式。
2.v-for指令搭档同行,ul和li是一对,tr和td是一对,漏单会报错。
3.做商品单价的时候可能用到的小技巧toFixed(保留几位小数)方法。
(1)
就只是想单纯地实现这样的效果。
(2)通过methods定义也是可以实现的。
(3)通过filters定义的过滤器也是可以实现的(推荐),同methods定义类似。
4.v-for遍历数据时,需要避免某个插件之间相互影响,可以使用index的下标作为methods的参数区分。
5.使用v-bind:disabled=" 布尔值",能够让用户动态交互地决定数量的下限(以前我们是使用if体条件语句判断的)。
比如我们要设置购买的数量,点击减号按钮,数量在减少时,不能出现为负数的存在,这种场景就应用到我们的v-bind:disabled=" "了。
关于disabled属性布尔值判断: