Vue项目中点击加入购物车按钮后购物车集合计数未按预期增长如何解决
问题根因
你的功能不生效主要是三个核心问题导致的:
- 你用来跨组件传值的
EventBus没有提前注册,且Cart组件没有监听addItem事件,点击加入购物车发出的事件根本没有被购物车组件接收处理 - 你自定义的
CartCollection类通过修改原型继承数组的写法,不被Vue2的响应式系统支持,即使你把数据推进了购物车数组,页面也不会自动更新 - Cart组件模板里用到的
cart-item组件你没有注册,会触发组件未定义报错,阻塞页面渲染
修复方案
第一步:注册全局EventBus
在你所有组件代码的最开头(app.components.js第一行)添加如下代码,先把事件总线实例创建出来:
const EventBus = new Vue();
第二步:修改Cart组件,添加事件监听、修复响应式问题
直接把购物车存储改成Vue原生支持响应式的普通数组,省去自定义集合类的响应式兼容成本,修改后的Cart组件代码如下:
const Cart = Vue.component('Cart', { data() { return { // 直接用普通数组存,Vue默认支持响应式 cart: [] } }, // 组件创建完成后监听加购事件 created() { EventBus.$on('addItem', (item) => { // 可选:加逻辑避免重复添加同一个商品 const existed = this.cart.find(cartItem => cartItem.title === item.title) if (!existed) { this.cart.push(item) } }) }, // 组件销毁前移除事件监听,避免内存泄漏 beforeDestroy() { EventBus.$off('addItem') }, // 删掉未定义的cart-item组件引用,先直接渲染商品标题,你后续可以自己封装CartItem组件 template: ` <div class="card-columns"> <div v-for="item in cart" :key="item.title" class="card"> <div class="card-body"> <p>{{item.title}}</p> </div> </div> <div class="card"> <p>购物车内商品:{{cart.length}}</p> </div> </div> ` })
可选优化:保留自定义CartCollection的兼容方案
如果你一定要用自己写的CartCollection类,只需要在每次调用addItem之后手动触发组件更新即可,Cart组件代码如下:
const Cart = Vue.component('Cart', { data() { return { cart: new CartCollection() } }, created() { EventBus.$on('addItem', (item) => { this.cart.addItem(item) // 手动触发组件更新,解决自定义集合类的响应式失效问题 this.$forceUpdate() }) }, beforeDestroy() { EventBus.$off('addItem') }, template: ` <div class="card-columns"> <div v-for="item in cart" :key="item.title" class="card"> <div class="card-body"> <p>{{item.title}}</p> </div> </div> <div class="card"> <p>购物车内商品:{{cart.length}}</p> </div> </div> ` })
改完之后点击加购按钮,购物车的计数器就会正常更新了。
内容的提问来源于stack exchange,提问作者user15269806
相关产品推荐
相关产品推荐

