# 購物車練習專案
## 專案定位
**一句話描述**:使用 React + TypeScript + Context API 實作的單頁式購物車應用,展示現代化前端狀態管理與元件設計模式。
**目標使用者**:
- 學習 React 狀態管理的前端開發者
- 需要購物車功能參考實作的團隊
- 準備技術面試的求職者
**核心價值**:
- ✅ **完整購物車流程**:商品瀏覽 → 加入購物車 → 數量調整 → 結算總價
- ✅ **狀態管理示範**:使用 Context API + useReducer 管理全域狀態
- ✅ **TypeScript 類型安全**:完整的型別定義與介面設計
- ✅ **響應式設計**:支援桌面與行動裝置(RWD)
- ✅ **模組化架構**:元件、頁面、Context、型別分離清晰
---
## 網站大綱(Sitemap)
```
購物車專案
├── 🏠 首頁 (/)
│ └── 自動導向產品列表
│
├── 🛍️ 產品列表 (/products)
│ ├── 商品卡片展示(8 筆模擬資料)
│ ├── 商品資訊(標題、描述、價格、圖片)
│ └── 加入購物車按鈕
│
└── 🛒 購物車 (/cart)
├── 已加入商品列表
├── 數量調整(+/-)
├── 單品移除
├── 總金額計算
└── 清空購物車
```
**技術架構**:
- **前端框架**:React 18.2.0 + React Router 6.20.1
- **狀態管理**:Context API + useReducer
- **建置工具**:Vite 5.0.0
- **資料來源**:靜態模擬資料(無後端 API)
---
## 快速開始
### 安裝依賴
```bash
npm install
```
### 啟動開發伺服器
```bash
npm run dev
```
伺服器會在 `http://localhost:3000` 啟動並自動開啟瀏覽器。
### 生產建置
```bash
npm run build
```
建置產物將輸出至 `dist/` 資料夾。
### 預覽生產版本
```bash
npm run preview
```
### 程式碼檢查
```bash
npm run lint
```
---
## 環境變數
### 環境變數表格
| 名稱 | 用途(中文) | 出現位置 | 是否必填 | 預設值建議 |
|------|-------------|---------|---------|-----------|
| - | 本專案無需環境變數 | - | - | - |
**說明**:本專案為純前端靜態應用,未使用外部 API、資料庫或需要設定的環境變數。Vite 伺服器埠號已在 `vite.config.ts` 中設定為 3000。
### `.env.example`
```bash
# 本專案目前無需環境變數設定
# 若未來需要串接 API,可參考以下格式:
# VITE_API_BASE_URL=https://api.example.com
# VITE_APP_TITLE=購物車專案
```
---
## 資料夾結構
```
react-product-cart/
│
├── index.html # HTML 入口(載入 React 應用)
├── package.json # npm 依賴與腳本
├── tsconfig.json # TypeScript 主設定
├── tsconfig.node.json # TypeScript Node 環境設定(Vite)
├── vite.config.ts # Vite 建置工具設定(port 3000)
│
└── src/ # 原始碼目錄
├── main.tsx # React 應用入口(ReactDOM.render + BrowserRouter)
├── App.tsx # 主元件(路由配置 + CartProvider 包裹)
├── index.css # 全域樣式與 RWD 設計
│
├── components/ # 可重用 UI 元件
│ ├── Navbar.tsx # 導航列(含購物車圖示與數量徽章)
│ ├── ProductCard.tsx # 產品卡片(展示商品資訊 + 加入購物車按鈕)
│ └── CartItem.tsx # 購物車項目(數量調整 + 移除功能)
│
├── pages/ # 頁面層級元件
│ ├── ProductList.tsx # 產品列表頁面(顯示所有商品)
│ └── Cart.tsx # 購物車頁面(結算與管理購物車項目)
│
├── context/ # React Context 狀態管理
│ └── CartContext.tsx # 購物車全域狀態(useReducer + Context API)
│
├── data/ # 靜態資料
│ └── products.ts # 模擬商品資料(8 筆 Apple 產品)
│
└── types/ # TypeScript 型別定義
└── index.ts # 全域介面(Product, CartItem, CartContextType)
```
### 目錄用途說明
| 目錄/檔案 | 用途 |
|----------|------|
| `src/components` | 可重用的 UI 元件(導航列、產品卡片、購物車項目) |
| `src/pages` | 頁面層級元件(對應路由) |
| `src/context` | 全域狀態管理(購物車邏輯) |
| `src/data` | 靜態模擬資料 |
| `src/types` | TypeScript 型別與介面定義 |
| `vite.config.ts` | Vite 建置工具與開發伺服器設定 |
| `index.html` | HTML 入口檔案 |
---
## 常用指令
| 指令 | 用途 | 來源 |
|------|------|------|
| `npm run dev` | 啟動開發伺服器(port 3000,自動開啟瀏覽器) | `package.json` |
| `npm run build` | 生產建置(TypeScript 編譯 + Vite 打包) | `package.json` |
| `npm run preview` | 預覽生產版本 | `package.json` |
| `npm run lint` | ESLint 程式碼檢查 | `package.json` |
---
## API 與資料模型概觀
### 資料來源
本專案**不使用後端 API**,所有商品資料來自 `src/data/products.ts` 的靜態模擬資料。
### 主要資料模型
#### Product(商品)
```typescript
interface Product {
id: number; // 商品 ID
title: string; // 商品標題
description: string; // 商品描述
price: number; // 商品價格(新台幣)
image: string; // 商品圖片 URL
category: string; // 商品分類
}
```
**範例資料**(共 8 筆):
- MacBook Pro 16" (NT$79,900)
- iPhone 15 Pro (NT$36,900)
- AirPods Pro 2 (NT$7,490)
- iPad Air (NT$18,900)
- Apple Watch Series 9 (NT$12,900)
- Magic Keyboard (NT$10,900)
- Studio Display (NT$45,900)
- HomePod mini (NT$3,000)
#### CartItem(購物車項目)
```typescript
interface CartItem {
product: Product; // 商品物件
quantity: number; // 數量
}
```
#### CartContextType(購物車 Context 介面)
```typescript
interface CartContextType {
cartItems: CartItem[]; // 購物車項目陣列
addToCart: (product: Product) => void; // 加入商品
removeFromCart: (productId: number) => void; // 移除商品
updateQuantity: (productId: number, quantity: number) => void; // 更新數量
clearCart: () => void; // 清空購物車
getTotalItems: () => number; // 取得總數量
getTotalPrice: () => number; // 取得總金額
}
```
### 購物車狀態管理流程
購物車使用 **Context API + useReducer** 管理狀態,支援以下動作:
| 動作類型 | 觸發時機 | 行為 |
|---------|---------|------|
| `ADD_TO_CART` | 點擊「加入購物車」按鈕 | 若商品已存在則數量 +1,否則新增至購物車 |
| `REMOVE_FROM_CART` | 點擊「移除」按鈕 | 從購物車刪除該商品 |
| `UPDATE_QUANTITY` | 點擊數量調整按鈕(+/-) | 更新商品數量;若數量 ≤ 0 則移除 |
| `CLEAR_CART` | 點擊「清空購物車」按鈕 | 清空所有購物車項目 |
---
## 系統架構圖
```mermaid
flowchart TB
subgraph entry[入口與設定]
indexHTML[index.html - HTML入口]
mainTSX[main.tsx - React入口]
appTSX[App.tsx - 路由配置]
viteCfg[vite.config.ts - 建置工具]
tscfg[tsconfig.json - TypeScript設定]
end
subgraph context[狀態管理Context]
cartCtx[CartContext.tsx - 購物車Context]
end
subgraph pages[頁面Pages]
productList[ProductList.tsx - 產品列表頁]
cartPage[Cart.tsx - 購物車頁]
end
subgraph components[元件Components]
navbar[Navbar.tsx - 導航列]
productCard[ProductCard.tsx - 產品卡片]
cartItem[CartItem.tsx - 購物車項目]
end
subgraph data[資料Data]
products[products.ts - 模擬產品資料]
end
subgraph types[型別定義Types]
typesIdx[index.ts - TypeScript介面]
end
subgraph styles[樣式Styles]
indexCSS[index.css - 全域樣式]
end
indexHTML -->|載入| mainTSX
mainTSX -->|imports引用| appTSX
mainTSX -->|imports引用| indexCSS
appTSX -->|imports引用| cartCtx
appTSX -->|imports引用| navbar
appTSX -->|imports引用| productList
appTSX -->|imports引用| cartPage
navbar -->|imports引用| cartCtx
productList -->|imports引用| productCard
productList -->|imports引用| products
productCard -->|imports引用| cartCtx
productCard -->|imports引用| typesIdx
cartPage -->|imports引用| cartCtx
cartPage -->|imports引用| cartItem
cartItem -->|imports引用| cartCtx
cartItem -->|imports引用| typesIdx
cartCtx -->|imports引用| typesIdx
products -->|imports引用| typesIdx
productCard -->|加入購物車| cartCtx
cartItem -->|更新數量移除| cartCtx
navbar -->|讀取購物車數量| cartCtx
cartPage -->|讀取購物車項目總價| cartCtx
```
---
## 部署與 CI/CD
### 建議部署方案
本專案為純前端靜態應用,建議部署至以下平台:
#### 1. Vercel(推薦)
```bash
# 安裝 Vercel CLI
npm i -g vercel
# 部署
vercel
```
#### 2. Netlify
```bash
# 建置指令
npm run build
# 發布目錄
dist
```
#### 3. GitHub Pages
在 `vite.config.ts` 中設定 `base`:
```typescript
export default defineConfig({
base: '/your-repo-name/',
// ...其他設定
})
```
然後執行:
```bash
npm run build
# 將 dist/ 資料夾推送至 gh-pages 分支
```
### CI/CD 自動化建議
**GitHub Actions 工作流範例**(建議新增 `.github/workflows/deploy.yml`):
```yaml
name: Deploy to Vercel
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Build
run: npm run build
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
```
**目前狀態**:本專案尚未設定 CI/CD 工作流。
---
## 技術亮點
- ✨ **React 18 最佳實踐**:使用 Hooks、Context API、useReducer 模式
- ✨ **TypeScript 完整型別**:所有元件與函式均有型別定義
- ✨ **元件化設計**:高內聚、低耦合的模組架構
- ✨ **狀態管理示範**:展示複雜狀態的 Reducer 邏輯
- ✨ **響應式設計**:使用 CSS Grid 與 Flexbox 實作 RWD
- ✨ **開發體驗優化**:Vite 快速啟動、HMR 熱更新
---
## 授權
本專案為教學範例,可自由使用與修改。