VueJS移除购物车最后一项时出现__asyncLoader未定义错误求助
Vue3 Reactive购物车移除最后一项时
__asyncLoader未定义错误修复 问题场景
使用Vue3的reactive API实现极简购物车状态管理,当移除购物车中的最后一项商品时,控制台抛出错误导致应用停止运行,错误栈指向removeFromCart方法:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '__asyncLoader') at isAsyncWrapper (runtime-core.esm-bundler.js:2272:40) at unmount (runtime-core.esm-bundler.js:6090:40) at unmountComponent (runtime-core.esm-bundler.js:6212:13) at unmount (runtime-core.esm-bundler.js:6097:13) at unmountChildren (runtime-core.esm-bundler.js:6241:13) at unmount (runtime-core.esm-bundler.js:6115:17) at patch (runtime-core.esm-bundler.js:5070:13) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5711:17) at ReactiveEffect.run (reactivity.esm-bundler.js:187:25) at instance.update (runtime-core.esm-bundler.js:5745:56) isAsyncWrapper @ runtime-core.esm-bundler.js:2272 unmount @ runtime-core.esm-bundler.js:6090 unmountComponent @ runtime-core.esm-bundler.js:6212 unmount @ runtime-core.esm-bundler.js:6097 unmountChildren @ runtime-core.esm-bundler.js:6241 unmount @ runtime-core.esm-bundler.js:6115 patch @ runtime-core.esm-bundler.js:5070 componentUpdateFn @ runtime-core.esm-bundler.js:5711 run @ reactivity.esm-bundler.js:187 instance.update @ runtime-core.esm-bundler.js:5745 callWithErrorHandling @ runtime-core.esm-bundler.js:157 flushJobs @ runtime-core.esm-bundler.js:390 Promise.then (async) queueFlush @ runtime-core.esm-bundler.js:282 queueJob @ runtime-core.esm-bundler.js:276 (anonymous) @ runtime-core.esm-bundler.js:5743 triggerEffect @ reactivity.esm-bundler.js:397 triggerEffects @ reactivity.esm-bundler.js:387 trigger @ reactivity.esm-bundler.js:355 set2 @ reactivity.esm-bundler.js:526 removeFromCart @ store.js:30 onClick @ CartView.vue:48 callWithErrorHandling @ runtime-core.esm-bundler.js:157 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:166 invoker @ runtime-dom.esm-bundler.js:345
现有代码
Store实现
export const store = reactive({ cart: [], total: 0, removeFromCart(id) { this.cart = this.cart.filter((item) => item.id !== id); this.updateTotal(); }, updateTotal() { let total = 0; for (const item of this.cart) { total += item.price * item.quantity; } this.total = total; }, });
模板代码
<tr v-for="product in store.cart" :key="product.id" class="border-b border-t bg-white" > <th scope="row" class="h-24 w-20 whitespace-nowrap py-4 px-6 font-medium text-gray-900" > <img :src="product.image" :alt="product.title" /> </th> <td class="py-4 px-6 font-bold"> {{ product.title }} </td> <td class="flex-nowrap py-4 px-6 font-bold"> <i @click="store.reduceQty(product.id)" class="bi bi-chevron-left mr-3 cursor-pointer" ></i> <span>{{ product.quantity }}</span> <i @click="store.addQty(product.id)" class="bi bi-chevron-right ml-3 cursor-pointer" ></i> </td> <td class="py-4 px-6 font-bold">${{ product.price }}</td> <td class="py-4 px-6"> <i @click="store.removeFromCart(product.id)" class="bi bi-x-lg cursor-pointer" ></i> </td> </tr>
错误原因
该错误源于直接替换reactive数组的引用:this.cart = this.cart.filter(...)会创建新数组并覆盖原数组引用,当最后一个元素被移除时,Vue在卸载对应DOM节点时,内部异步加载器的引用因原数组被替换而丢失,导致无法读取__asyncLoader属性。
修复方案
方案1:使用数组变异方法(推荐)
保持原数组引用不变,使用splice方法移除目标元素,让Vue能正确跟踪数组变化:
removeFromCart(id) { const targetIndex = this.cart.findIndex(item => item.id === id); if (targetIndex !== -1) { this.cart.splice(targetIndex, 1); } this.updateTotal(); }
方案2:保留原数组引用更新内容
如果偏好使用filter,可以先清空原数组,再将过滤后的元素推入原数组,避免替换引用:
removeFromCart(id) { const filteredItems = this.cart.filter(item => item.id !== id); // 清空原数组 this.cart.length = 0; // 推入新元素,保持原数组引用 this.cart.push(...filteredItems); this.updateTotal(); }
验证
修改后,移除购物车最后一项时,数组引用保持不变,Vue能正确处理DOM卸载逻辑,不会再抛出__asyncLoader未定义的错误。
内容的提问来源于stack exchange,提问作者Talha Meer
相关产品推荐
相关产品推荐

