购物车需要展示一个已加入购物车的商品列表,包含商品名称、商品单价、购买数量和操作等信息,还需要实时显示购买总价。其中购买数量可以增加或减少,每类商品还可以从购物车中移除。
练习1:在当前示例基础上扩展商品列表,新增一项是否选中该商品的功能,总价变为只计算选中商品的总价,同时提供一个全选的按钮。
练习2:将商品列表list改为一个二维数组来实现商品的分类,比如可分为“电子产品” “生活用品” 和“果蔬”,同类商品聚合在一起。提示,你可能会用到两次v-for。
练习2 html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="app" v-cloak>
<template v-if="list.length">
<table>
<thead>
<tr>
<th></th>
<th>商品名称</th>
<th>商品单价</th>
<th>购买数量</th>
<th>操作</th>
<th>
<!-- <button @click="selectAll">全选</button> -->
全选<input type="checkbox" @click="dealSelectAll" :checked="isSelectAll">
</th>
</tr>
</thead>
<tbody>
<template v-for="(item,index) in list">
<tr>
<td colspan="6" class="shopClass">{{ item.title }}
<input type="checkbox" @click="goodsSelectAll(index)" :checked="item.isSelect">
</td>
</tr>
<tr v-for="(subItem, subIndex) in item.list">
<td>{{ subIndex + 1 }}</td>
<td>{{ subItem.name }}</td>
<td>{{ subItem.price }}</td>
<td>
<button
@click="handleReduce(index,subIndex)"
:disabled="subItem.count === 1">-</button>
{{ subItem.count }}
<button @click="handleAdd(index,subIndex)">+</button>
</td>
<td>
<button @click="handleRemove(index,subIndex)">移除</button>
</td>
<td>
<input type="checkbox" @click="dealSelect(index,subIndex)" :checked="subItem.isSelect">
</td>
</tr>
</template>
</tbody>
</table>
<div>总价:¥ {{ totalPrice }}</div>
</template>
<div v-else>购物车为空</div>
</div>
<!-- vue引导一定要再js脚本前,不然会报错 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./index.js"></script>
</body>
</html>
练习2 js:
var app = new Vue({
el: '#app',
data: {
isSelectAll: false,
list: [
{
isSelect: false,
title: '电子产品',
list: [
{
id: 1001,
name: 'iphone7',
price: 6188,
count: 1,
isSelect: false
},
{
id: 1002,
name: 'ipad Pro',
price: 5888,
count: 1,
isSelect: false
},
{
id: 1003,
name: 'MacBook Pro',
price: 21488,
count: 1,
isSelect: false
}
]
},
{
title: '生活用品',
isSelect: false,
list: [
{
id: 2001,
name: '洗面奶',
price: 68,
count: 1,
isSelect: false
},
{
id: 2002,
name: '沐浴露',
price: 48,
count: 1,
isSelect: false
},
{
id: 2003,
name: '香皂',
price: 18,
count: 1,
isSelect: false
}
]
},
{
isSelect: false,
title: '果蔬',
list: [
{
id: 3001,
name: 'apple',
price: 8,
count: 1,
isSelect: false
},
{
id: 3002,
name: 'banana',
price: 3,
count: 2,
isSelect: false
},
{
id: 3003,
name: 'tomato',
price: 5,
count: 1,
isSelect: false
}
]
}
]
},
computed: {
totalPrice: function(){
var total = 0;
for(shop of this.list){
for(goods of shop.list){
if(goods.isSelect){
total += goods.price * goods.count;
}
}
}
return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');//转换为带有千位分隔符的数字
}
},
methods: {
handleReduce: function(index,subIndex){
var shop = this.list[index];
if(shop.list[subIndex].count === 1) return;
shop.list[subIndex].count--;
},
handleAdd: function(index,subIndex){
var shop = this.list[index];
shop.list[subIndex].count++;
},
handleRemove: function(index,subIndex){
var shop = this.list[index];
shop.list.splice(subIndex,1);
},
goodsSelectAll: function(index){
var _this = this;
var shop = _this.list[index];
shop.isSelect = !shop.isSelect;
for(goods of shop.list){
goods.isSelect = shop.isSelect;
}
var isSelectAllShop = true;
for(shop of _this.list){
if(shop.isSelect==false){
isSelectAllShop=false;
}
}
if(isSelectAllShop){
_this.isSelectAll=true;
}else{
_this.isSelectAll=false;
}
},
dealSelect: function(index,subIndex){
var _this = this;
var shop = _this.list[index];
// shop.isSelect = !shop.isSelect;
var goods = shop.list[subIndex];
goods.isSelect = !goods.isSelect;
//判断所有商品是否被选中
var isSelectAllGoods = true;
for(goods of shop.list){
if(goods.isSelect==false){
isSelectAllGoods=false;
}
}
if(isSelectAllGoods){
shop.isSelect=true;
}else{
shop.isSelect=false;
}
//判断所有商铺是否被选中
var isSelectAllShop = true;
for(shop of _this.list){
if(shop.isSelect === false){
isSelectAllShop = false;
}
}
if(isSelectAllShop){
_this.isSelectAll=true;
}else{
_this.isSelectAll=false;
}
},
dealSelectAll: function(){
var _this = this;
_this.isSelectAll = !_this.isSelectAll;
for(shop of _this.list){
shop.isSelect = _this.isSelectAll;
for(goods of shop.list){
goods.isSelect = _this.isSelectAll;
}
}
}
}
})
练习2 css:
var app = new Vue({
el: '#app',
data: {
isSelectAll: false,
list: [
{
isSelect: false,
title: '电子产品',
list: [
{
id: 1001,
name: 'iphone7',
price: 6188,
count: 1,
isSelect: false
},
{
id: 1002,
name: 'ipad Pro',
price: 5888,
count: 1,
isSelect: false
},
{
id: 1003,
name: 'MacBook Pro',
price: 21488,
count: 1,
isSelect: false
}
]
},
{
title: '生活用品',
isSelect: false,
list: [
{
id: 2001,
name: '洗面奶',
price: 68,
count: 1,
isSelect: false
},
{
id: 2002,
name: '沐浴露',
price: 48,
count: 1,
isSelect: false
},
{
id: 2003,
name: '香皂',
price: 18,
count: 1,
isSelect: false
}
]
},
{
isSelect: false,
title: '果蔬',
list: [
{
id: 3001,
name: 'apple',
price: 8,
count: 1,
isSelect: false
},
{
id: 3002,
name: 'banana',
price: 3,
count: 2,
isSelect: false
},
{
id: 3003,
name: 'tomato',
price: 5,
count: 1,
isSelect: false
}
]
}
]
},
computed: {
totalPrice: function(){
var total = 0;
for(shop of this.list){
for(goods of shop.list){
if(goods.isSelect){
total += goods.price * goods.count;
}
}
}
return total.toString().replace(/\B(?=(\d{3})+$)/g, ',');//转换为带有千位分隔符的数字
}
},
methods: {
handleReduce: function(index,subIndex){
var shop = this.list[index];
if(shop.list[subIndex].count === 1) return;
shop.list[subIndex].count--;
},
handleAdd: function(index,subIndex){
var shop = this.list[index];
shop.list[subIndex].count++;
},
handleRemove: function(index,subIndex){
var shop = this.list[index];
shop.list.splice(subIndex,1);
},
goodsSelectAll: function(index){
var _this = this;
var shop = _this.list[index];
shop.isSelect = !shop.isSelect;
for(goods of shop.list){
goods.isSelect = shop.isSelect;
}
var isSelectAllShop = true;
for(shop of _this.list){
if(shop.isSelect==false){
isSelectAllShop=false;
}
}
if(isSelectAllShop){
_this.isSelectAll=true;
}else{
_this.isSelectAll=false;
}
},
dealSelect: function(index,subIndex){
var _this = this;
var shop = _this.list[index];
// shop.isSelect = !shop.isSelect;
var goods = shop.list[subIndex];
goods.isSelect = !goods.isSelect;
//判断所有商品是否被选中
var isSelectAllGoods = true;
for(goods of shop.list){
if(goods.isSelect==false){
isSelectAllGoods=false;
}
}
if(isSelectAllGoods){
shop.isSelect=true;
}else{
shop.isSelect=false;
}
//判断所有商铺是否被选中
var isSelectAllShop = true;
for(shop of _this.list){
if(shop.isSelect === false){
isSelectAllShop = false;
}
}
if(isSelectAllShop){
_this.isSelectAll=true;
}else{
_this.isSelectAll=false;
}
},
dealSelectAll: function(){
var _this = this;
_this.isSelectAll = !_this.isSelectAll;
for(shop of _this.list){
shop.isSelect = _this.isSelectAll;
for(goods of shop.list){
goods.isSelect = _this.isSelectAll;
}
}
}
}
})
效果截图: