基础练习做一个购物车示例如下:
一、添加表格结构样式及数据
<div>
<table>
<tr>
<td></td>
<td>书本id</td>
<td>书本名称</td>
<td>书本价格</td>
<td>操作</td>
</tr>
<tr>
<td><input type="checkbox" ></td>
<td>合计</td>
<td></td>
<td></td>
<td><button>计算</button></td>
</tr>
</table>
</div>
table,table tr th, table tr td { border:1px solid #0094ff; }
table { width: 500px; min-height: 25px; line-height: 25px; text-align: center; border-collapse: collapse;}
books:[
{id:1,name:'书籍001',price:10},
{id:2,name:'书籍002',price:20},
{id:3,name:'书籍003',price:55},
{id:4,name:'书籍004',price:79},
{id:5,name:'书籍004',price:39},
]
二、填充表格数据
v-for填充数据
v-for 遍历数组: v-for=" (item,[index]) in 数组" 遍历map:v-for="
(value,[key],[index]) in 对象"
<tr v-for="item in books" :key="item.id">
<td><input type="checkbox" ></td>
<td>{{ item.id}}</td>
<td>{{ item.name}}</td>
<td>{{ item.price}}</td>
<td><button>删除</button></td>
</tr>
使用计算属性计算总价格
computed:{
totalPrice:{
get(){
return this.books.reduce((s,n)=>s+n.price,0);
}
}
},
这样就可以把总价钱放到表格中了。
监听删除事件
<td><button @click="delBook(item.id)">删除</button></td>
delBook(id){
this.books = this.books.filter(x=>x.id!==id);
}
监听单选及全选
声明一个selectBook用于区分选择元素和未选择元素
selectBooks:[],
<td><input type="checkbox" @click="onCheckbox($event.target.checked,item)"></td>
onCheckbox(checked,item){
if(checked){
this.selectBooks.push(item);
}else{
if(this.selectBooks.indexOf(item)>=0){
this.selectBooks.splice(this.selectBooks.indexOf(item),1);
}
}
}
计算总价的属性改为选择的元素,也就是selectBooks
为全选添加方法,
<td><input type="checkbox" @click="checkAllBox($event.target.checked)"></td>
并给每条数据添加动态选择属性,
关联全选与单选
checkAllBox(e){
if(e){
this.isAllCheckBox = true;
}else{
this.isAllCheckBox = false;
}
}
如果全选则需要把books里面的数据存放到selectbooks,反之则移除
checkAllBox(e){
if(e){
this.isAllCheckBox = true;
this.selectBooks = this.selectBooks.concat(this.books)
}else{
this.isAllCheckBox = false;
this.selectBooks = [];
}
}
优化
可以发现测试的是取消单选,则全选依然被选中。
可以给全选按钮也添加
:checked="allCheckBox"
allCheckBox:false,
如果所有数据都选中,则全选也被选中。
if(this.selectBooks.length===this.books.length){
this.allCheckBox=true;
}
当选中该数据,然后删除的时候,总计数据不会删除。所以删除元素的时候需要从选中数组中移除。
this.selectBooks = this.selectBooks.filter(x=>x.id!==id);
完整代码如下:
<template>
<div>
<table>
<tr>
<td></td>
<td>书本id</td>
<td>书本名称</td>
<td>书本价格</td>
<td>操作</td>
</tr>
<tr v-for="item in books" :key="item.id">
<td><input type="checkbox" :checked="isAllCheckBox" @click="onCheckbox($event.target.checked,item)"></td>
<td>{{ item.id}}</td>
<td>{{ item.name}}</td>
<td>{{ item.price}}</td>
<td><button @click="delBook(item.id)">删除</button></td>
</tr>
<tr>
<td><input type="checkbox" :checked="allCheckBox" @click="checkAllBox($event.target.checked)"></td>
<td>合计</td>
<td></td>
<td>{{totalPrice}}</td>
<td><button>计算</button></td>
</tr>
</table>
</div>
</template>
<script>
export default {
data(){
return {
isAllCheckBox:false,
allCheckBox:false,
selectBooks:[],
books:[
{id:1,name:'书籍001',price:10},
{id:2,name:'书籍002',price:20},
{id:3,name:'书籍003',price:55},
{id:4,name:'书籍004',price:79},
{id:5,name:'书籍004',price:39},
]
};
},
computed:{
totalPrice:{
get(){
return this.selectBooks.reduce((s,n)=>s+n.price,0);
}
}
},
methods:{
delBook(id){
this.books = this.books.filter(x=>x.id!==id);
this.selectBooks = this.selectBooks.filter(x=>x.id!==id);
},
onCheckbox(checked,item){
if(checked){
this.selectBooks.push(item);
}else{
this.allCheckBox = false;
if(this.selectBooks.indexOf(item)>=0){
this.selectBooks.splice(this.selectBooks.indexOf(item),1);
}
}
this.allCheckBox = this.selectBooks.length === this.books.length;
},
checkAllBox(e){
this.selectBooks = [];
if(e){
this.allCheckBox = true;
this.isAllCheckBox = true;
this.selectBooks = this.selectBooks.concat(this.books)
}else{
this.allCheckBox = false;
this.isAllCheckBox = false;
}
}
}
}
</script>
<style>
table,table tr th, table tr td { border:1px solid #0094ff; }
table { width: 500px; min-height: 25px; line-height: 25px; text-align: center; border-collapse: collapse;}
</style>
还有个bug不会解决。
首先全选,然后取消单选,然后再全选,每一条不会选中