Nuxt3项目部署Vercel后Pinia的cartStore读取undefined报错
Nuxt3 + Pinia部署Vercel后购物车按钮报错:
TypeError: Cannot read properties of undefined (reading 'cartStore') 问题现象
本地通过npm run dev运行Nuxt3项目一切正常,但部署至Vercel服务器后,点击触发购物车渲染的按钮时出现错误,浏览器控制台报错:
TypeError: Cannot read properties of undefined (reading 'cartStore')
相关代码
按钮组件代码
<UiButton :variant="cartStore.isInCart(card.id) ? 'success' : 'action'" @click="handleAddToCart(card.id, card.selectedRate)" class="mt-auto"> {{ cartStore.isInCart(card.id) ? 'В корзине' : 'В корзину' }} <svg-icon v-if="cartStore.isInCart(card.id)" name="check-success" width="16" height="16" /> </UiButton>
点击处理函数
function handleAddToCart(cardId, selectedRate) { if (!selectedRate) { alert('Пожалуйста, выберите тарифный план.'); return; } this.cartStore.addItem(cardId, selectedRate.id); }
组件环境代码
import { useCartStore } from '@/stores/cart'; import { onMounted } from 'vue'; import cardsData from '~/src/data/cards-data.json'; import ratesData from '~/src/data/rates-data.json'; onMounted(async () => { await Promise.all([ cartStore.setCardsData(cardsData), cartStore.setRatesData(ratesData) ]); }); const selectedRate = ref('');
Pinia的cart.js存储文件
import { defineStore } from 'pinia' export const useCartStore = defineStore('cart', { state: () => ({ cartItems: {}, // Объект вида { id: { count, rateId } } cardsData: [], ratesData: [], }), actions: { addItem(id, rateId) { if (this.cartItems[id]) { this.cartItems[id].count++ } else { this.cartItems[id] = { count: 1, rateId } } }, }, })
已尝试方案
- 重装Pinia旧版本包
- 在
package.json中配置vue:latest
以上操作均未解决问题,本地日志正常,服务器上无法捕获addItem函数的日志,其他日志与本地一致。
问题根源与修复方案
根源分析
报错核心原因是:
- 组件中导入了
useCartStore但未调用该函数创建/获取存储实例,直接使用未定义的cartStore变量 - Nuxt3的
<script setup>语法中不存在组件实例this,生产构建时this.cartStore会直接失效 - Pinia存储中缺失模板调用的
isInCart、setCardsData、setRatesData方法
修复步骤
1. 正确初始化Pinia存储实例
在组件代码中必须调用useCartStore()获取实例,修改组件环境代码:
import { useCartStore } from '@/stores/cart'; import { onMounted, ref } from 'vue'; import cardsData from '~/src/data/cards-data.json'; import ratesData from '~/src/data/rates-data.json'; // 调用useCartStore获取存储实例 const cartStore = useCartStore(); onMounted(async () => { await Promise.all([ cartStore.setCardsData(cardsData), cartStore.setRatesData(ratesData) ]); }); const selectedRate = ref('');
2. 修改处理函数的调用方式
<script setup>中无需使用this,直接调用已初始化的cartStore实例:
function handleAddToCart(cardId, selectedRate) { if (!selectedRate) { alert('Пожалуйста, выберите тарифный план.'); return; } cartStore.addItem(cardId, selectedRate.id); // 移除this }
3. 补充Pinia存储中缺失的方法
在cart.js的actions中补充模板调用的方法:
actions: { addItem(id, rateId) { if (this.cartItems[id]) { this.cartItems[id].count++ } else { this.cartItems[id] = { count: 1, rateId } } }, // 补充isInCart方法 isInCart(id) { return !!this.cartItems[id]; }, // 补充setCardsData方法 setCardsData(data) { this.cardsData = data; }, // 补充setRatesData方法 setRatesData(data) { this.ratesData = data; } },
4. 确认Nuxt3中Pinia的基础配置
确保项目已正确配置Pinia:
- 安装依赖:
npm install @pinia/nuxt pinia - 在
nuxt.config.ts中添加模块:
export default defineNuxtConfig({ modules: ['@pinia/nuxt'], })
内容的提问来源于stack exchange,提问作者Roman Nemerсev
相关产品推荐
相关产品推荐

