PHP与Vue.js前后端分离项目实战开发详解:从零搭建电商购物车系统

作为一名全栈开发者,我在多个项目中实践了PHP与Vue.js的前后端分离架构。今天我想通过一个电商购物车系统的完整开发过程,与大家分享这种架构模式的实战经验。前后端分离不仅提升了开发效率,更让团队协作变得更加顺畅。

一、环境准备与项目初始化

首先我们需要搭建开发环境。后端使用PHP 7.4+和Laravel框架,前端使用Vue 3和Vite构建工具。

后端环境搭建:

# 创建Laravel项目
composer create-project laravel/laravel shopping-cart-api
cd shopping-cart-api

# 安装必要的扩展包
composer require laravel/sanctum
composer require intervention/image

前端项目初始化:

# 创建Vue项目
npm create vue@latest shopping-cart-frontend
cd shopping-cart-frontend
npm install axios vue-router@4 pinia

踩坑提示:确保PHP版本兼容Laravel要求,Node.js版本建议使用LTS版本,避免兼容性问题。

二、后端API设计与开发

我们先设计购物车系统的核心API接口:商品列表、加入购物车、查看购物车、更新数量、删除商品。

创建商品模型和迁移:

// database/migrations/2024_01_01_create_products_table.php
public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description');
        $table->decimal('price', 8, 2);
        $table->integer('stock');
        $table->string('image_url')->nullable();
        $table->timestamps();
    });
}

商品控制器实现:

// app/Http/Controllers/ProductController.php
public function index()
{
    $products = Product::where('stock', '>', 0)
        ->select('id', 'name', 'price', 'image_url', 'stock')
        ->paginate(12);
    
    return response()->json([
        'status' => 'success',
        'data' => $products
    ]);
}

public function show($id)
{
    $product = Product::findOrFail($id);
    return response()->json([
        'status' => 'success',
        'data' => $product
    ]);
}

购物车API实现时,我选择了Session存储方案,实际项目中可根据需求改用Redis或数据库:

// app/Http/Controllers/CartController.php
public function addToCart(Request $request)
{
    $request->validate([
        'product_id' => 'required|exists:products,id',
        'quantity' => 'required|integer|min:1'
    ]);

    $cart = session()->get('cart', []);
    $productId = $request->product_id;

    if(isset($cart[$productId])) {
        $cart[$productId]['quantity'] += $request->quantity;
    } else {
        $cart[$productId] = [
            'quantity' => $request->quantity,
            'added_at' => now()
        ];
    }

    session()->put('cart', $cart);
    
    return response()->json([
        'status' => 'success',
        'message' => '商品已加入购物车'
    ]);
}

三、前端Vue.js组件开发

前端我们使用Vue 3的Composition API,配合Pinia进行状态管理。

商品列表组件:

// src/components/ProductList.vue


购物车状态管理:

// src/stores/cart.js
import { defineStore } from 'pinia'

export const useCartStore = defineStore('cart', {
  state: () => ({
    items: [],
    loading: false
  }),
  
  actions: {
    async addItem(product) {
      this.loading = true
      try {
        const response = await axios.post('/api/cart/add', {
          product_id: product.id,
          quantity: 1
        })
        
        // 更新本地状态
        const existingItem = this.items.find(item => item.id === product.id)
        if (existingItem) {
          existingItem.quantity += 1
        } else {
          this.items.push({ ...product, quantity: 1 })
        }
        
        ElMessage.success(response.data.message)
      } catch (error) {
        ElMessage.error('加入购物车失败')
      } finally {
        this.loading = false
      }
    }
  },
  
  getters: {
    totalPrice: (state) => {
      return state.items.reduce((total, item) => {
        return total + (item.price * item.quantity)
      }, 0)
    },
    
    itemCount: (state) => {
      return state.items.reduce((count, item) => count + item.quantity, 0)
    }
  }
})

四、前后端联调与跨域处理

在开发过程中,前后端分离项目最常见的坑就是跨域问题。我在Laravel后端配置CORS:

// config/cors.php
return [
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://localhost:3000'],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

前端配置API代理,避免跨域问题:

// vite.config.js
export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})

五、性能优化与部署建议

在实际部署时,我总结了几点优化经验:

后端API响应优化:

// 使用缓存减少数据库查询
public function index()
{
    $products = Cache::remember('products:list', 3600, function () {
        return Product::where('stock', '>', 0)
            ->select('id', 'name', 'price', 'image_url', 'stock')
            ->get();
    });
    
    return response()->json($products);
}

前端代码分割优化:

// 路由懒加载
const ProductList = () => import('@/components/ProductList.vue')
const Cart = () => import('@/components/Cart.vue')

部署建议:后端使用Nginx + PHP-FPM,前端使用Nginx部署静态文件,或者使用Docker容器化部署。

六、项目总结与扩展思考

通过这个完整的购物车项目,我深刻体会到前后端分离架构的优势:前后端可以并行开发、技术栈选择更灵活、便于后续维护扩展。

在实际项目中,还可以进一步扩展:

  • 集成支付接口(支付宝、微信支付)
  • 实现用户认证和权限管理
  • 添加商品搜索和筛选功能
  • 实现订单管理和物流跟踪

前后端分离不是银弹,需要根据项目规模和团队情况选择合适的架构。对于小型项目,过度分离可能增加复杂度;对于中大型项目,这种架构能显著提升开发效率和系统可维护性。

希望这篇实战教程能帮助你在PHP和Vue.js前后端分离开发中少走弯路。如果在实践中遇到问题,欢迎在评论区交流讨论!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。