# 購物車練習專案 ## 專案定位 **一句話描述**:使用 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 熱更新 --- ## 授權 本專案為教學範例,可自由使用與修改。