题目描述
完成购物车,完成对应商品的选择和取消的功能
题目来源及自己的思路
《Vue.js实战》第五章
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
<!DOCTYPE html>
<html lang="cmn-hans">
<head>
<meta charset="utf-8">
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<!--PC端必选 强制360浏览器使用webkit渲染 -->
<meta name="renderer" content="webkit">
<!--必选 for PC -->
<link rel="stylesheet" type="text/css" href="css.css">
<title>购物车</title>
</head>
<body>
<div>
<p>购物车需求</p>
<ol>
<li>展示已经加入购物车的商品列表</li>
<li>商品列表包含商品名称,商品单价,购买数量和操作能力</li>
<li>能够实时显示所购买的总价</li>
<li>商品数量可以增加,减少或者直接移除</li>
</ol>
</div>
<hr>
<!-- 页面挂载点 -->
<div id="app" v-cloak>
<template v-if="goods.length">
<table>
<thead>
<tr>
<td>表头</td>
<td>商品名称</td>
<td>商品单价</td>
<td>购买数量</td>
<td>操作</td>
<td>选择 | 全选<input type="checkbox" @click="selectAll" id="selectAll" :checked="isCheckedAll"></td>
</tr>
</thead>
<tbody>
<tr v-for="good,index in goods">
<td>{{index+1}}</td>
<td>{{good.name}}</td>
<td>{{good.price}}</td>
<!-- 数量调整 -->
<td>
<button @click="reduce(index)" :disabled="good.count === 1">-</button>
{{good.count}}
<button @click="add(index)">+</button>
</td>
<!-- 操作 -->
<td>
<button @click="remove(index)">移除</button>
</td>
<td>
<input type="checkbox" @click="select(index,$event)" class="select">
</td>
</tr>
</tbody>
</table>
<div><p> 全部总价:¥{{totalPrice}}</p>
<p>选中总价: ¥{{selectPrice}}</p>
</div>
</template>
<div v-else>购物车是空的</div>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="trolley.js"></script>
</body>
</html>
css.css:
table {
border: 1px solid #ccc;
}
thead {
background-color: #ddd;
}
td {
border: 1px solid #ccc;
}
trolley.js:
var app = new Vue({
el: '#app',
data: {
//商品数据
goods: [
{ id: 1, name: 'iphone 7', price: 6188, count: 1 },
{ id: 2, name: 'ipad Pro', price: 5888, count: 1 },
{ id: 3, name: 'MacBook Pro', price: 21488, count: 1 }
],
selectPrice: 0,
isCheckedAll: false ,//初始化没有全选择
isChecked:false
},
computed: {
totalPrice: function() {
var total = 0;
for (var i = 0; i < this.goods.length; i++) {
total += this.goods[i].price * this.goods[i].count;
}
return total;
}
},
methods: {
reduce: function(index) {
//再次判断 reduce 减法的可靠性
if (this.goods[index].count === 1) return;
this.goods[index].count--;
},
add: function(index) {
this.goods[index].count++;
},
remove: function(index) {
//删除一条数组数据
this.goods.splice(index, 1);
},
selectAll: function() {
if (this.isCheckedAll) {
for (let i = 0; i < this.goods.length; i++) {
document.querySelectorAll(".select")[i].checked = false;
}
} else {
for (let i = 0; i < this.goods.length; i++) {
document.querySelectorAll(".select")[i].checked = true;
}
}
this.isCheckedAll = !this.isCheckedAll;
},
select: function(index, event) {
if (document.querySelectorAll(".select")[index].checked) {
document.querySelectorAll(".select")[index].checked = true;
//逐步全部选中及后续
} else {
document.querySelectorAll(".select")[index].checked = false;
//逐步全部不选中及后续
}
}
},
});
你期待的结果是什么?实际看到的错误信息又是什么?
目前完成了单选和全选功能,但是实际在操作过程中应该在逐个选中之后,全选按钮选中,和逐个取消选中之后,全选按钮最后也取消选中状态,没有完成。
我觉得思路应该是每次单选/取消单选的时候都要循环判断全部的checkbox是全部选中/全部不选中,然后再设置全选按钮的状态。但是不知道应该怎么写。
其他答案提到,需要使用computed,这是正确的,因为是否isCheckedAll是需要“实时”查看各个check的值的变化的,故使用computed比较适合。
顺便简化了一下你的代码,第一可以将每个物品的选中与否设计成goods的字段,这样逻辑清楚些;第二 select和selectAll方法重写了下,以供参考。
代码如下: