目录
一、需求说明
二、代码实现
三、运行效果
四、业务技术点总结
案例中的图片和样式资源文件夸克网盘分享地址:
链接:https://pan.quark.cn/s/17cc56cea97f
一、需求说明
1. 渲染功能
2. 删除功能(v-on,methods)
3. 修改个数(v-on,methods)
4. 全选反选(computed,集合的every方法,集合的foreach方法)
5. 统计选中的总价和总数量(computed)
6. 持久化到本地(localStorage)
二、代码实现
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><link rel="stylesheet" href="./css/inputnumber.css" /><link rel="stylesheet" href="./css/index.css" /><title>购物车</title></head><body><div class="app-container" id="app"><!-- 顶部banner --><div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" /></div><!-- 面包屑 --><div class="breadcrumb"><span>🏠</span>/<span>购物车</span></div><!-- 购物车主体 --><div class="main" v-if="fruitList.length > 0"><div class="table"><!-- 头部 --><div class="thead"><div class="tr"><div class="th">选中</div><div class="th th-pic">图片</div><div class="th">单价</div><div class="th num-th">个数</div><div class="th">小计</div><div class="th">操作</div></div></div><!-- 身体 --><div class="tbody"><div v-for="(item, index) in fruitList" :key="item.id" class="tr" :class="{ active: item.isChecked}"><div class="td"><input type="checkbox" v-model="item.isChecked"/></div><div class="td"><img :src="item.icon" alt="" /></div><div class="td">{{ item.price }}</div><div class="td"><div class="my-input-number"><button :disabled="item.num < 2" class="decrease" @click="sub(item.id)"> - </button><span class="my-input__inner">{{ item.num }}</span><button class="increase" @click="add(item.id)"> + </button></div></div><div class="td">{{ item.num * item.price }}</div><div class="td"><button @click="del(item.id)">删除</button></div></div></div></div><!-- 底部 --><div class="bottom"><!-- 全选 --><label class="check-all"><input type="checkbox" v-model="isAll"/>全选</label><div class="right-box"><!-- 所有商品总价 --><span class="price-box">总价 : ¥ <span class="price">{{ totalPrice }}</span></span><!-- 结算按钮 --><button class="pay">结算( {{ totalCount }} )</button></div></div></div><!-- 空车 --><div class="empty" v-else>🛒空空如也</div></div><script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script><script>const defaultArrList = [{id: 1,icon: './img/火龙果.png',isChecked: true,num: 2,price: 6,},{id: 2,icon: './img/荔枝.png',isChecked: false,num: 7,price: 20,},{id: 3,icon: './img/榴莲.png',isChecked: false,num: 3,price: 40,},{id: 4,icon: './img/鸭梨.png',isChecked: true,num: 10,price: 3,},{id: 5,icon: './img/樱桃.png',isChecked: false,num: 20,price: 34,},]const app = new Vue({el: '#app',data: {// 水果列表 项目中正常逻辑是优先从缓存中取,缓存中没有则返回一个空列表(避免报错导致页面显示异常)// fruitList: JSON.parse(localStorage.getItem('list')) || []// 这里我们为了演示方便,如果缓存为空,直接赋值一个初始的水果列表fruitList: JSON.parse(localStorage.getItem('list')) || defaultArrList},computed: {// 因为需要同时获取和设置,所以这里要用到计算属性的完整写法isAll: {get () {// 必须所有的小选框都选中,全选按钮才选中 -> 用到集合的every方法return this.fruitList.every(item => item.isChecked)},set (value) {// 基于拿到的布尔值,让所有的小选框同步状态this.fruitList.forEach(item => item.isChecked = value)}},// 计算选中的总数,用到集合的reduce方法totalCount () {return this.fruitList.reduce((sum, item) => {if (item.isChecked) {// 选中 -> 累加return sum + item.num} else {// 没选中 -> 不累加return sum}sum + item.num}, 0)},// 计算选中的总价 累加每样商品 num * pricetotalPrice () {return this.fruitList.reduce((sum, item) => {if (item.isChecked) {return sum + item.num * item.price} else {return sum}}, 0)}},methods: {del (id) {this.fruitList = this.fruitList.filter(item => item.id !== id)},add (id) {// 1.根据id找到数组中的对应项 -> 集合的find方法const fruit = this.fruitList.find(item => item.id === id)// 2.操作num数量fruit.num++},sub (id) {// 1.根据id找到数组中的对应项 -> 集合的find方法const fruit = this.fruitList.find(item => item.id === id)// 2.操作num数量fruit.num--}},watch: {fruitList: {deep: true,handler (newValue) {// 将变化后的newValue存入本地(转JSON)localStorage.setItem('list', JSON.stringify(newValue))}}}})</script></body>
</html>
三、运行效果
四、业务技术点总结
1. 渲染功能: v-if/v-else v-for :class
2. 删除功能: 点击传参 filter过滤覆盖原数组
3. 修改个数:点击传参 find找对象
4. 全选反选:计算属性computed 完整写法 get/set
5. 统计选中的总价和总数量: 计算属性computed reduce条件求和
6. 持久化到本地: watch监视,localStorage,JSON.stringify, JSON.parse