无法在 Vue.js + Nuxt 3 + Pinia Store 中将产品添加到购物车

问题描述 投票:0回答:1

我几天来一直在努力让我的 Vue.js 应用程序使用 Pinia 商店将产品添加到购物车。我的后端是用 Laravel 构建的,我正在发出 API 请求以将商品添加到购物车。尽管尝试了各种解决方案,我仍然遇到产品未添加到购物车的问题。

问题:

当我尝试将产品添加到购物车时,我希望添加产品并更新购物车。然而,未添加该产品。以下是我的代码的相关部分。

Vue.js 代码(Pinia 商店):

// stores/CartStore.ts
import { defineStore, acceptHMRUpdate } from "pinia";
import { addProductToCart, getCartData } from '@/services/api';
import { notify } from "@kyvg/vue3-notification";

interface CartItem {
  product_detail_id: number;
  name: string;
  product_image: string;
  price: number;
  quantity: number;
}

const useCartStore = defineStore("CartStore", {
  state: () => ({
    cartItems: [] as CartItem[],
  }),
  actions: {
    async addProductToCart(productDetailId: number, quantity: number) {
      try {
        const response = await addProductToCart(productDetailId, quantity);
        if (response.status) {
          await this.fetchCartData(); // Refresh cart data
          notify({
            type: "success",
            text: "Product has been added to cart successfully 🎉!",
            duration: 500,
          });
        }
      } catch (error) {
        console.error('Error adding product to cart:', error);
        notify({
          type: "error",
          text: "Failed to add product to cart",
          duration: 500,
        });
      }
    },
    async fetchCartData() {
      try {
        const response = await getCartData();
        if (response.status) {
          this.cartItems = response.data;
        }
      } catch (error) {
        console.error('Error fetching cart data:', error);
      }
    },
    removeItemFromCart(productDetailId: number) {
      this.cartItems = this.cartItems.filter(cartItem => cartItem.product_detail_id !== productDetailId);
      notify({
        type: "success",
        text: "Product has been removed from cart successfully 🎉!",
        duration: 500,
      });
    },
  },
  getters: {
    numberOfProductsInCart(state) {
      return state.cartItems.reduce((acc, item) => acc + item.quantity, 0);
    },
    totalAmountOfProductsInCart(state) {
      return state.cartItems.reduce((acc, item) => acc + (item.price * item.quantity), 0);
    },
    productsInCart(state) {
      return state.cartItems;
    },
  },
});

// make sure to pass the right store definition, `useAuth` in this case.
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useCartStore, import.meta.hot));
}

export default useCartStore;

API服务:

// services/api.ts
import { useFetch } from 'nuxt/app';
import {
  ADD_PRODUCT_TO_CART_URL,
  CART_DATA_URL
} from '@/constants/urls';

// Carts Data
export const addProductToCart = async (productDetailId: number, quantity: number) => {
  const formData = new FormData();
  formData.append('product_detail_id', productDetailId.toString());
  formData.append('quantity', quantity.toString());

  const data = await useFetch(ADD_PRODUCT_TO_CART_URL, {
    method: 'POST',
    body: formData,
  });

  return data.value;
};

export const getCartData = async () => {
  const data = await useFetch(CART_DATA_URL);
  return data.value;
};

常量 URLS

//constants/urls.ts
export const API_BASE_URL = 'https://example.com/api';

// Carts Data
export const ADD_PRODUCT_TO_CART_URL: string = `${API_BASE_URL}/carts-data`;
export const ADD_BUNDLE_TO_CART_URL: string = `${API_BASE_URL}/carts-data`;
export const CART_DATA_URL: string = `${API_BASE_URL}/carts-data`;

Laravel 控制器:

// app/Http/Controllers/User/AddToCartController.php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Http\Requests\User\StoreCartRequest;
use App\Http\Resources\User\AddToCartResource;
use App\Models\CartItem;
use App\Services\User\AddToCartService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AddToCartController extends Controller
{
    public function __construct(protected AddToCartService $addToCartService)
    {
    }

    public function store(StoreCartRequest $request): JsonResponse
    {
        try {
            $this->addToCartService->createCartItem($request->validated());
            return response()->success('Product added to cart Successfully');
        } catch (Exception) {
            return response()->fail();
        }
    }
}

Laravel 请求:

// app/Http/Requests/User/StoreCartRequest.php

namespace App\Http\Requests\User;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class StoreCartRequest extends FormRequest
{
    protected function prepareForValidation(): void
    {
        $this->merge([
            'user_id' => Auth::id() ?: null,
            'session_id' => Auth::check() ? null : $this->session()->getId(),
        ]);
    }

    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'user_id' => 'nullable|integer|exists:users,id',
            'session_id' => 'nullable|string',
            'product_detail_id' => [
                'integer',
                'exists:product_details,id',
                'required_without:bundle_id'
            ],
            'quantity' => [
                'required',
                'integer',
                'min:1',
            ],
        ];
    }
}

我尝试过的:

  1. 使用
    curl
    验证 API 端点,返回成功的响应。
  2. 检查从前端发送的有效负载,确保其符合 API 要求。
  3. 确保后端路由和控制器正确配置并正常工作。

预期行为:

将产品添加到购物车时,应触发 API 调用,添加产品并相应更新购物车状态。

实际行为:

产品未添加到购物车。但是,当使用

curl
进行测试时,API 返回成功的响应。

控制台日志

api.ts:189 [nuxt] [useFetch] 组件已挂载,请使用 $fetch 代替。看 https://nuxt.com/docs/getting-started/data-fetching

product-slug-1:1 访问获取 来自原点的“https://example.com/api/carts-data” “http://localhost:3000”已被 CORS 策略阻止:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。 api.ts:189

POST https://example.com/api/carts-data net::ERR_FAILED 403 (禁止)

任何有关我可能做错或遗漏的事情的帮助或指示将不胜感激!

typescript cors vuejs3 nuxt3.js laravel-11
1个回答
0
投票

这是您

CORS
方面的
API
配置问题。仅当从浏览器发出请求时才会遇到
CORS
问题,因此这解释了为什么您在使用
curl
或其他
API
工具时看不到它们。发生这种情况是因为
API
服务器不允许来自其他服务器(例如在您的
localhost
上运行的服务器)的请求。

您的错误告诉您,您的

Access-Control-Allow-Origin
上没有
API
标头。当从
CORS
返回响应时,您可以在
API
预检中设置以下内容,以允许来自所有来源的请求:

Access-Control-Allow-Origin: "*"

查看本指南,了解有关启用

CORS
的一般信息。

对于

Laravel
,看起来您需要使用此配置

© www.soinside.com 2019 - 2024. All rights reserved.