内容 Content
- 购物车仓库设计 cart.js
- 购物车组件设计 Cart.vue
- 购物车组件运用
. 为避免重复操作添加数据,可以预先准备一些测试数据,如下
. 详情请查看 状态管理应用 - 购物车
const lists = ref([ { id: 0, title: "coffee", price: 9, discount: 0.2, stock: 10, quantity: 1 }, { id: 1, title: "cup", price: 5, discount: 0.4, stock: 10, quantity: 1 }, { id: 2, title: "code", price: 16, discount: 0.1, stock: 10, quantity: 1 }, { id: 3, title: "cookie", price: 8, discount: 0.5, stock: 10, quantity: 1 }, ]);
. 详情请查看 侦听综合运用 - 购物车
. 封装为一个组件
. 固定定位在菜单视图底部;弹性盒子方向调整为垂直;折叠时,由 footer 撑开;展开时,背景设为透明黑
. header 和 main 折叠时不显示 - 条件渲染
. header 设置外边距上为自动,撑开购物车
. main 指定最大高度;信息区可以设置单点溢出...
. footer 折叠时,背景为空;展开时设置白色
<div class="cart" :class="{ 'show-cart': isShow }"> <header v-show="isShow"> // ... </header> <main v-show="isShow"> <div class="cart-item" v-for="item in 4"> // ... </div> </main> <footer> <div class="cont"> // ... </div> </footer> </div>
. 购物车固定定位在详情页底部;没有封装
. 基本结构,无数据绑定、无事件
. 高度同主导航;网格布局;平分空间;保持间隔;其它价格部分单独设置结束对齐
. 按钮的初始化和相关变量均来自主样式文件 app.css
<div class="cart"> <span class="price">¥<span>99</span>起</span> <div class="opers"> <button class="oper dec">-</button> <div class="quantity">1</div> <button class="oper inc">+</button> </div> <button class="btn btn-cart">加入购物车</button> <button class="btn btn-buy">立即购买</button> </div>
. 在 onMounted 中已经获取到了商品数据;需要准备添加到购物车的数据;
. 利用解构处理/清洗数据,格式同原始数据保持一致;同名字段,后面的会覆盖前面的
. 增加一个数量字段 quantity,默认是1
. 处理规格 specification;规格组件的封装,请参考 组件双向绑定 defineModel - 规格组件 specification
. 这里没有处理甜点 dessert 和推荐商品 recommend
// 商品仓库 goods.js 中读取的数据 const good = ref({}) // 清洗后的数据,加入到购物车仓库 cart.js 中 const goodSelected = ref({})
onMounted(async () => { let res = await goodsStore.getById(route.params.id) good.value = res goodSelected.value = { ...res, quantity: 1, specification: [ { name: 'cup', value: res.specification[0].options.find(item => item.sel == true).label }, { name: 'ther', value: res.specification[1].options.find(item => item.sel == true).label }, { name: 'sugar', value: res.specification[2].options.find(item => item.sel == true).label, }], dessert: [], recommend: [] } })
. 为数量按钮绑定单击事件
. 利用按钮的 disabled 处理越界;只判断下边界
. 这里使用内联事件实现
<div class="opers"> <button class="oper dec" @click="goodSelected.quantity--" :disabled="goodSelected.quantity <= 1">-</button> <div class="quantity">{{ goodSelected.quantity }}</div> <button class="oper inc" @click="goodSelected.quantity++">+</button> </div>
. 使用计算 computed()处理;也可以使用监听 watch()
const total = computed(() => { return (goodSelected.value.price * (1 - goodSelected.value.discount) * goodSelected.value.quantity).toFixed(2) })
. 为加入购物车指定事件 addToCarts
. 创建购物车数据项:增加新字段 productId,保存商品 id;商品原 id 字段可以保留,也可以移除
. 数据项的 id 可以在这里指定;也可以在购物车仓库中指定;这里由购物车仓库指定
. 跳转到菜单视图;这里使用替换 replace 模式
const addToCarts = () => { const cartItem = { ...goodSelected.value, productId: goodSelected.value.id, }; cartStore.addToCarts(cartItem) router.replace('/menu') alert('Added to carts') }
. 略
. 使用响应式数据替换掉上述静态结构中的数据
. 完善详情页中其它部分
. 更多效果自行完成