HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>购物车示例</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="app" v-cloak>
<template v-if="allListNum">
<table>
<thead>
<tr>
<th>
<input type="checkbox" v-model="checkAll">全选
</th>
<th>商品名称</th>
<th>商品单价</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<template v-for="(item,index) in list">
<tr v-if="item.content.length">
<td colspan="5">{{item.name}}</td>
</tr>
<tr v-for="(small,smallIndex) in item.content">
<!-- <td>{{index+1}}</td> -->
<td><input type="checkbox" :checked="small.check" @click="isAll(index,smallIndex)"> {{small.check}}</td>
<td>{{small.name}}</td>
<td>{{small.price}}</td>
<td>
<button @click="handleReduce(index,smallIndex)" :display="small.count===1">-</button>
{{small.count}}
<button @click="handleAdd(index,smallIndex)">+</button>
</td>
<td>
<button @click="handleRemove(index,smallIndex)">移除</button>
</td>
</tr>
</template> </tbody>
</table>
<div>总价:¥{{totalPrice}}</div>
</template>
<div v-else>
购物车为空
</div>
</div>
<script src="../../vue.js"></script>
<script src="./index.js"></script>
</body>
</html>

JS:

var app=new Vue({
el:'#app',
data:{
list:[
{
name:'电子产品',
content:[
{
id:1,
name:'iPhone 7',
price:6288,
count:1,
check:false
},{
id:2,
name:'iPad Pro',
price:5888,
count:1,
check:false
},{
id:3,
name:'MacBook Pro',
price:21488,
count:1,
check:false
}
]
},{
name:'图书',
content:[
{
id:1,
name:'《小王子》',
price:10000000000,
count:1,
check:false
},{
id:2,
name:'《失控》',
price:100,
count:1,
check:false
},{
id:3,
name:"《目送》",
price:40,
count:1,
check:false
},{
id:4,
name:'《爱与孤独》',
price:10,
count:1,
check:false
}
]
} ],
checkAll:false,
smallHand:false
},
computed:{
totalPrice:function(){
var arr=[];
for(var i=0;i<this.list.length;i++){
arr=arr.concat(this.list[i]['content']);
}
this.newList=arr.filter(function(item){
if(item.check){
return item;
}
});
var total=0;
for(var i=0;i<this.newList.length;i++){
var item=this.newList[i];
total+=item.price*item.count;
}
return total.toString().replace(/\B(?=(\d{3})+$)/g,',');//匹配后面已3个数字结尾的非单词边界,换成“,”
/* replace:
用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串
\B :匹配非单词边界
(red|blue|green):查找任何指定的选项
?=n :匹配任何其后紧接指定字符串n的字符串(n量词) 提供后面的n找?
\d :查找数字
n{X}:匹配包含X个n的序列字符串
\d{3}:匹配含有3个数字的字符串
n$ :匹配任何结尾为n的字符串
n+ :匹配任何包含至少一个n的字符串
(\d{3})+$ :匹配至少一个已含有3个数字字符串结尾的字符
*/
},
allListNum:function(){
var allNum=0;
for(var i=0;i<this.list.length;i++){
var item=this.list[i]['content'];
for(var j=0;j<item.length;j++){
allNum++;
}
}
return allNum;
}
},
methods:{
handleReduce:function(index,smallIndex){
console.log(index);
console.log(smallIndex);
if(this.list[index]['content'][smallIndex].count===1) return;
this.list[index]['content'][smallIndex].count--;
},
handleAdd:function(index,smallIndex){
this.list[index]['content'][smallIndex].count++;
},
handleRemove:function(index,smallIndex){
this.list[index]['content'].splice(smallIndex,1);
var num=0;
for(var i=0;i<this.list.length;i++){
var item=this.list[i]['content'];
for(var j=0;j<item.length;j++){
if(item[j].check){
num++;
}else{
num--;
}
}
}
if(num==this.allListNum){
this.checkAll=true;
}else{
this.checkAll=false;
}
},
isAll:function(index,smallIndex){
console.log(this.list[index]['content'][smallIndex].check);
var indexItem=this.list[index]['content'][smallIndex]; indexItem.check=!indexItem.check;
var num=0;
for(var i=0;i<this.list.length;i++){
var item=this.list[i]['content'];
for(var j=0;j<item.length;j++){
if(item[j].check){
num++;
}else{
num--;
}
}
}
console.log(num);////(选中了最后一个)3-全部勾选-勾选全选 (之前全部勾选,取消了任意一个勾选) 1-取消全选的勾选
// if(num==7||(num==5&&indexItem.check==false)){ 这里的值不能写死,太笨了 if(num==this.allListNum||(num==(this.allListNum-2)&&indexItem.check==false)){
this.checkAll=indexItem.check;
this.smallHand=true;
}
}
},
watch:{
checkAll:function(){
if(this.smallHand){ }else{
for(var i=0;i<this.list.length;i++){
var list=this.list;
for(var j=0;j<list[i]['content'].length;j++){
this.list[i]['content'][j]['check']=this.checkAll;
}
}
}
this.smallHand=false;
}
}
})

CSS:

[v-cloak] {
display: none;
}
table {
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing:;
empty-cells: show;
}
table th,
table td {
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
table th {
background: #f7f7f7;
color: #5c6b77;
font-weight:;
white-space: nowrap;
}

总结:相比前一个购物车,这个购物车可实现物品分类,数据又多了一层嵌套。

 

最新文章

  1. FragmentPagerAdapter+ViewPager+Fragment
  2. meta
  3. vim ---- 一键自动indent的命令
  4. Redis复制与可扩展集群搭建
  5. 创建DAO模式的步骤
  6. world machine, 输出lightmap
  7. c# 框架学习(nop )总结-------编辑功能
  8. Metasploit 笔记
  9. Hive(四):c#通过odbc访问hive
  10. Ext.Net学习笔记06:Ext.Net DirectEvents用方补充
  11. Httpservlet cannot be resolved to a type
  12. json处理三部曲之第一曲:利用json-lib-xxx.jar处理json
  13. 基于Metronic的Bootstrap开发框架经验总结(15)-- 更新使用Metronic 4.75版本
  14. SQL Server中自定义函数:用指定的分隔符号分割字符串
  15. Linux下Clamav 杀毒软件安装使用文档
  16. perl 读取一个文件 替换文件的关键词 把数据替换到新的文件
  17. stm32最简单的实现BootLoader
  18. 检查Linux系统cpu--内存---磁盘的脚本
  19. 20165205 《Java程序设计》第一周学习总结
  20. MVC003之调用BLL层方法(BLL层调用了WebService)

热门文章

  1. 从零开始学安全(三十八)●cobaltstrike生成木马抓肉鸡
  2. Web.config中customErrors异常信息配置
  3. Restful API设计规范及实战
  4. Java开发笔记(三十)大小数BigDecimal
  5. 零基础学Python--------入门篇 第1章 初始Python
  6. ASP.NET SignalR介绍
  7. 开源介绍&#183;新款简约、实用与大气的Hexo新主题:BMW
  8. 自定义HorizontalScrollView的scrollBar
  9. Android 解析标准的点击第三方文件管理器中的视频的intent
  10. AspNetCore.FileLog 一款很不错的日志记录工具