使用Vue制作一个购物车小案例
1. html
<div id="app" class="table-box">
<table class="common-table table-bordered table-striped table-hover">
<colgroup>
<col width="5%" />
<col width="10%" />
<col width="25%" />
<col width="10%" />
<col width="10%" />
<col width="15%" />
<col width="10%" />
<col width="15%" />
</colgroup>
<thead>
<tr>
<th>
<!-- 使用change而不用click是因为 click 执行比 model绑定快一步,数据是不对的 -->
<input type="checkbox" name="all" v-model="isall" @change="checkall" />
</th>
<th>ID</th>
<th>品名</th>
<th>单位</th>
<th>单价/元</th>
<th>数量</th>
<th>金额/元</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- key索引最好不要用 index, 若是存在分页情况可能会出现问题 -->
<tr v-for="(item, index) in goods" :key="item.id">
<td>
<!-- input checkbox 中不管 checked 为何值,只要有就是选中状态 -->
<!-- <input type="checkbox" name="id" checked /> -->
<!-- Vue中的复选框 v-model 可以是boolean值,也可以是数组,数值元素就是 value -->
<input type="checkbox" :value="item" v-model="checklist" />
</td>
<td class="a-left">{{ item.id }}</td>
<td class="a-left">{{ item.name }}</td>
<td>{{ item.unit }}</td>
<td class="price">{{ item.price }}</td>
<td class="count">
<button @click="item.count--" :disabled="item.count < 1">-</button>
{{ item.count }}
<!-- 使用disabled直接进行库存加购限制 -->
<button @click="item.count++" :disabled="item.count >= item.stock">+</button>
</td>
<td class="item-amount">{{ item.price * item.count }}</td>
<td>
<button @click="deletegood(item.id)">移除商品</button>
</td>
</tr>
</tbody>
<tfoot>
<tr class="summary">
<td colspan="5">总计</td>
<td>{{ sum().count }}</td>
<td>{{ sum().amount }}</td>
<td></td>
</tr>
</tfoot>
</table>
<!-- {{ checklist }} -->
</div>
2. js
var obj = {
data() {
return {
// 选中列表
checklist: [],
// 是否全选
isall: false,
// 商品列表
goods: [{
id: 'SN-0001',
name: '小米Redmi Note8',
unit: '台',
price: 999,
count: 1,
stock: 99, // 库存
}, {
id: 'SN-0002',
name: '华为 HUAWEI Mate 30 Pro',
unit: '台',
price: 6399,
count: 1,
stock: 11, // 库存
}, {
id: 'SN-0003',
name: '华为 HUAWEI P40 Pro',
unit: '台',
price: 5988,
count: 1,
stock: 2, // 库存
}]
}
},
watch: {
checklist(value) {
// 通过对checklist监听来判断全选状态
this.isall = (value.length == this.goods.length && this.goods.length > 0) ? true : false
}
},
methods: {
sum() {
// 求和 -- forEach方式
// let amount = 0
// let count = 0
// this.checklist.forEach(item => {
// amount += item.price * item.count
// count += item.count
// })
// return { amount, count }
// 求和 -- reduce方式
// return {
// amount: this.checklist.reduce((total, item) => {
// return total + item.price * item.count
// }, 0),
// count: this.checklist.reduce((total, item) => {
// return total + item.count
// }, 0)
// }
// 求和 -- reduce方式优化
return this.checklist.reduce((total, item) => {
return {
amount: total.amount + item.price * item.count,
count: total.count + item.count,
}
}, { amount: 0, count: 0 })
},
// 全选
checkall() {
this.checklist = this.isall ? this.goods : []
},
// 选中数组的同步操作
deletegood(id) {
// 删除对应商品
this.goods = this.goods.filter(item => item.id != id)
// 选中数组删除对应商品
this.checklist = this.checklist.filter(item => item.id != id)
}
}
}
let vm = Vue.createApp(obj).mount('#app')
3. 效果图
4. 开发中的一些小要点
- 复选框值的绑定
<input type="checkbox" :value="item" v-model="checklist" />
这里使用数组来绑定复选框,可以赋值value为商品的某一项,这样使得后续拿到完整数据,比如拿id: item.id
2. 总计求和通过定义sum方法得到,当然放到watch监听checklist中也同样可以,这里是为了看起来更直观些(主要是因为懒,不想再定义两个初始总计数据,后续想扩展几个就直接sum中加就行了)
sum() {
...
}
- 对商品数量的限制使用disabled实现
<button @click="item.count--" :disabled="item.count < 1">-</button>
{{ item.count }}
<!-- 使用disabled直接进行库存加购限制 -->
<button @click="item.count++" :disabled="item.count >= item.stock">+</button>
- 删除商品方法参数方法不建议使用index(易出问题), 使用唯一编号id不会出错
deletegood(id) {
// 删除对应商品
this.goods = this.goods.filter(item => item.id != id)
// 选中数组删除对应商品
this.checklist = this.checklist.filter(item => item.id != id)
}
ps: 这里直接替换原数组是最方便的(偷懒了),若是遇到业务复杂的删除,不建议这么做,老老实实去删除对应元素