# 🧰 Vue + Vite 前端專案初始化全 🔖 整合來源: * [《🧰 專案初始化流程總覽:讓專案跑得起來的第一步》](https://hackmd.io/@63Ywhax5TLKtGhFSWnacvQ/By4uDI5rex) * [《🧰 Vue + Vite 專案初始化流程指南》](https://hackmd.io/@63Ywhax5TLKtGhFSWnacvQ/SJhwwIqHlx) --- ## 🧱 一、專案初始化概念與工具總覽 📌 來源整合:〈總覽〉 + 〈指南〉 建立一個完整的 Vue 前端專案,從來不只是打開 VSCode 開始寫畫面而已。實務上,開發前的第一步,是要幫整個專案鋪好「能跑起來的環境」,這件事稱為「專案初始化」。 這個過程不僅包含 Vite + Vue 的骨架建立,還包括環境變數 `.env` 設定、Node.js 的後端模擬、開發用工具(如 ESLint / Prettier / 插件懶人註冊)的安裝、UI 套件整合、Router 與 Store 的啟用等。 這份筆記會幫你: 1. 🎯 從頭到尾建立一個 Vue + Vite 的可執行專案 2. 🧩 裝好「開發好用工具」與「UI 套件」 3. 🗂 建立清楚的資料夾結構與 main.js 啟動流程 4. 🔧 串接 API 並處理跨域(含 axios 與 proxy) 5. 🛠 延伸進階懶人工具與動畫/互動元件 --- ### 🔍 開發環境的三大層次概念(出自〈總覽〉) | 層次 | 說明與重點 | | ------------- | --------------------------------------------------------- | | 🧱 專案骨架 | 使用 Vite 建立 Vue 專案、初始化資料夾、安裝 router 等基本依賴 | | 🛠 開發效率工具包 | 安裝實用工具(如 ESLint、Prettier、auto-import、vite-plugin-inspect) | | 🎨 UI 套件與樣式整合 | PrimeVue(或其他框架)整合與樣式引入 | --- ### 📦 開箱即用的初始化觀念 * 每個 UI 框架幫你做的事情不一樣,要去比對官方文件看它幫你處理了什麼 * `main.js` 是 Vue 專案的大腦,「整合插件與樣式的總司令」 * `.env` 是前後端協作中極其重要的橋梁 * 懶人工具 ≠ 懶惰,是讓你專注邏輯與維護效率的超級助力 --- ## 🪜 二、Vue + Vite 初始化流程步驟 📌 來源整合:〈指南〉主幹 + 〈總覽〉補充細節 這一區塊是從零開始建立 Vue + Vite 專案的流程,包含建立前端專案骨架、初始化 Node 環境、設定 `.env` 檔與 `.gitignore`,並安裝 `vue-router` 路由功能。 --- ### Step 1️⃣ 建立 Vue + Vite 專案骨架 透過 Vite 提供的快速初始化指令建立新專案: ```bash npm create vite@latest ``` 依照指示輸入: ``` ✔ Project name: » vite-project(← 你想要的專案名稱) ✔ Select a framework: » Vue ✔ Select a variant: » JavaScript ``` 然後進入資料夾並安裝: ```bash cd vite-project npm install ``` --- ### Step 2️⃣ 初始化 Node 環境(模擬後端或搭配 Express) 雖然主軸是前端,但實務開發一定會串接 API,建議一併初始化 Node 專案與常用工具: ```bash npm init --yes npm i -D nodemon ``` 📌 `nodemon`:自動偵測檔案變動,自動重啟伺服器,開發後端 Express API 時超好用。 --- ### Step 3️⃣ 建立 `.env` 與 `.gitignore` 這兩個不是自動生成,要你手動建立。 #### 📝 `.env`:放環境變數(API 路徑、port 等) ```dotenv PORT=3000 VITE_API_BASE_URL=http://localhost:3000 ``` 📌 注意:**只有以 `VITE_` 開頭的變數才能被前端讀取!** --- #### 📝 `.gitignore`:讓 Git 忽略不該上傳的內容 ```gitignore .env node_modules dump/* !dump/.gitkeep ``` 📌 `.gitkeep` 是一個技巧,用來保留空資料夾(Git 預設不會追蹤空資料夾)。 --- ### Step 4️⃣ 安裝 Vue Router 並建立基本路由設定 ```bash npm i vue-router ``` 建立檔案: ``` src/router/index.js src/views/HomeView.vue ``` `router/index.js` 範例: ```js import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' const routes = [{ path: '/', component: HomeView }] export default createRouter({ history: createWebHistory(), routes, }) ``` 📌 `HomeView.vue` 可放簡單的 `<template><h1>Home</h1></template>` 當作測試畫面。 --- ## ⚙️ 三、主程式 main.js 組裝流程 📌 來源整合:〈總覽〉 + 〈指南〉 在 Vue 專案中,`main.js` 是整個應用的啟動點,它會負責: 1. 建立 Vue App 實體 2. 掛載 UI 套件(如 PrimeVue) 3. 掛載插件(如 Pinia、Router) 4. 匯入全域樣式與資源 5. 把應用掛載到 `index.html` 的 `#app` 上 --- ### 📂 `main.js` 最基本範例 ```js import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.mount('#app') ``` 這段程式是 Vue 的最小啟動形式。 --- ### 💡 專案中實際常見的完整版本(整合 Pinia、PrimeVue、Router) ```js import { createApp } from 'vue' import App from './App.vue' // 🌟 PrimeVue UI 套件與樣式 import PrimeVue from 'primevue/config' import 'primevue/resources/themes/lara-light-blue/theme.css' // 主題樣式 import 'primevue/resources/primevue.min.css' // 元件樣式 import 'primeicons/primeicons.css' // 圖示樣式 import 'primeflex/primeflex.css' // 排版工具(選用) // 🧠 狀態管理 import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' // 🚦 Router(使用 vue-router) import router from './router' // 或自動路由請看下一節 const app = createApp(App) // 📌 掛載插件與元件 app.use(PrimeVue) const pinia = createPinia() pinia.use(piniaPluginPersistedstate) app.use(pinia) app.use(router) app.mount('#app') ``` --- ### 🧠 每個步驟解釋 | 匯入項目 | 用途說明 | | ------------------------- | ------------------------------------------------ | | `PrimeVue` + 樣式 | 設定 PrimeVue UI 套件、載入主題與基本樣式、圖示庫與排版工具 | | `createPinia()` + persist | 啟用狀態管理與資料持久化(登入、token、購物車等常見場景) | | `router` | 註冊前端路由控制,讓 `<router-view>` 可以正確切換畫面 | | `.mount('#app')` | 把整個 App 掛載到 `index.html` 中的 `<div id="app">` 元素上 | --- ### 📦 PrimeVue 元件註冊提醒 PrimeVue 不會自動讓元件可以用,建議你用「集中註冊」方式管理: ```js // plugins/primevue.js import Button from 'primevue/button' import Dialog from 'primevue/dialog' export default (app) => { app.component('Button', Button) app.component('Dialog', Dialog) } ``` 然後在 `main.js` 使用: ```js import registerPrimeVue from './plugins/primevue' registerPrimeVue(app) ``` 這樣一來,不只可讀性高,也方便統一管理與更新元件。 --- ## 🗂 四、資料夾結構與命名建議 📌 來源整合:〈總覽〉 + 〈指南〉 🎯 目的:幫助你建立一套「好讀好維護的專案資料夾結構」 --- ### 🏗 推薦的 Vue 專案資料夾結構總覽 ``` 📁 src/ ├── assets/ # 靜態圖像與樣式(圖片、音效、字型等) ├── styles/ # 全域樣式(SCSS、變數、reset) ├── components/ # 可重用 UI 元件(按鈕、彈窗、欄位) ├── views/ # 頁面元件(對應路由畫面,通常搭配 router) ├── layouts/ # 畫面版型(default.vue, admin.vue 等) ├── router/ # Vue Router 設定(若使用手動路由) ├── store/ # 狀態管理(pinia 資料夾,可替代為 `pinia/`) ├── plugins/ # 插件初始化(PrimeVue, i18n, VeeValidate 等) ├── composables/ # 自定義 `useXXX()` 工具函式 ├── services/ # axios API 請求封裝(如 userService.js) ├── constants/ # 靜態資料、對照表、表單選項等 ├── utils/ # 純邏輯工具函式(非 Vue,資料轉換/運算邏輯等) ├── App.vue # 主元件(整個應用畫面的容器) └── main.js # Vue 應用啟動點 ``` --- ### 📚 每個資料夾用途說明表格 | 資料夾名稱 | 📦 職責 | 🔍 說明與常見內容 | | -------------- | -------- | ------------------------------------------------------- | | `assets/` | 靜態資源區 | 圖片、影片、音效、字型,能直接用於 `<img src>` | | `styles/` | 全域樣式設定 | SCSS 主題變數、reset.css、共用樣式模組 | | `components/` | 可重用元件 | 小型 UI 元件:按鈕、Modal、表單欄位等,使用 `props`/`slots` 提高彈性 | | `pages/` | 頁面元件 | 路由對應畫面元件,每個頁面一個 `.vue` | | `layouts/` | 頁面版型 | 用於 `vite-plugin-vue-layouts-next`,設定 default/admin 畫面框架 | | `router/` | 前端路由設定 | 若使用手動路由,在這裡管理 `index.js` 等 | | `store/` | 全域狀態管理 | 使用 Pinia 管理如登入資訊、購物車、Token 等 | | `plugins/` | 插件初始化 | 用於集中註冊 PrimeVue、VeeValidate 等,讓 main.js 更乾淨 | | `composables/` | 自定義邏輯工具 | 自製 `useXXX()` 函式,強化 Composition API 模組化 | | `services/` | API 請求封裝 | 放各種後端 API 封裝,例如 `userService.js`、`orderService.js` | | `constants/` | 常數定義資料 | 狀態對照表、表單選項、錯誤代碼等 | | `utils/` | 純邏輯函式 | 非 Vue 專用邏輯,例如格式轉換、數字計算、驗證工具等 | --- ### 🧭 建立時機與命名小提醒 | 建立時機 | 建議 | | -------------- | ---------------------- | | `.env` | 有 API 時立即建立 | | `router/` | 安裝 `vue-router` 後 | | `store/` | 有登入/購物車/共用資料需求時建立 | | `services/` | 有任何 API 請求前就該建立 | | `plugins/` | 安裝 Vue Plugin 就應建立初始化檔 | | `composables/` | 需要跨元件共用的功能邏輯時建立 | --- ### 📦 命名慣例整理 | 概念項目 | 建議命名 | 補充說明 | | ------------- | ------------------------- | --------------------------------------- | | API 請求封裝區 | `services/` | 命名如 `userService.js`,可集中維護路徑與邏輯 | | 狀態管理資料夾 | `store/` | 也可用 `pinia/`,選一種固定全專案一致即可 | | 工具函式區 | `utils/` | 命名如 `formatDate.js`, `calculateWeek.js` | | 靜態常數對照表區 | `constants/` | 命名如 `statusMap.js`, `formOptions.js` | | 可重用元件 vs 頁面元件 | `components/` vs `views/` | 前者為積木模組,後者為對外整頁畫面 | --- ## 📦 五、開發套件說明與使用技巧 📌 來源整合:〈總覽〉 + 〈指南〉 🎯 本章會依功能分類整理所有重要開發套件,幫助你理解每個套件的用途、安裝方式與搭配使用技巧。 --- ### 🧰 類別一:Vue 基礎輔助工具 | 套件名稱 | 功能說明 | | --------------------- | --------------------------------------------------------------------------------- | | `@vueuse/core` | Vue 的實用工具函式庫,提供許多 `useXXX()` 開頭的 Composition API 函式(如:`useMouse()`、`useDark()` 等) | | `vite-plugin-inspect` | 查看 Vite 插件運作情況(瀏覽 `/__inspect` 頁面可除錯) | 📦 安裝指令: ```bash npm i @vueuse/core npm i -D vite-plugin-inspect ``` --- ### 🔍 類別二:語法風格與格式工具(ESLint + Prettier) | 套件 | 功能說明 | | ------------------------ | ------------------------------- | | `eslint` | 檢查程式語法、邏輯錯誤 | | `prettier` | 統一排版格式(如縮排、分號、引號等) | | `eslint-plugin-prettier` | 讓 Prettier 整合進 ESLint 流程 | | `eslint-config-prettier` | 關掉 ESLint 跟 Prettier 重疊的規則,避免衝突 | | `eslint-plugin-vue` | 專門針對 `.vue` 檔的 ESLint 規則檢查 | 📦 安裝指令: ```bash npm init @eslint/config@latest npm i -D eslint prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-vue ``` 📄 ESLint 設定範例:`eslint.config.js` 📄 Prettier 設定範例:`.prettierrc.json` (見前面內容已完整提供) --- ### 🎨 類別三:UI 套件整合(PrimeVue) | 套件名稱 | 功能說明 | | ------------ | ------------------------------------------ | | `primevue` | 提供各種內建 UI 元件,如 `<Button>`、`<Dialog>` 等 | | `primeicons` | 圖示庫,可透過 `<i class="pi pi-check"></i>` 使用 | | `primeflex` | 類似 Tailwind 的工具類別排版系統(`.flex`, `.gap-2` 等) | 📦 安裝指令: ```bash npm i primevue@latest primeicons primeflex ``` 📂 在 `main.js` 中匯入對應樣式與 `.use(PrimeVue)` 即可使用。 🧠 小提醒:元件需手動註冊,可集中寫在 `plugins/primevue.js` 統一管理。 --- ### 🧠 類別四:狀態管理(Pinia) | 套件名稱 | 功能說明 | | ----------------------------- | ---------------------------------- | | `pinia` | Vue 官方推薦的狀態管理(取代 Vuex) | | `pinia-plugin-persistedstate` | 將狀態儲存在 localStorage,支援登入紀錄、跨頁狀態保存等 | 📦 安裝指令: ```bash npm i pinia pinia-plugin-persistedstate ``` 📄 在 `main.js` 中: ```js const pinia = createPinia() pinia.use(piniaPluginPersistedstate) app.use(pinia) ``` --- ### 🔌 類別五:後端互動與 API 封裝 | 套件名稱 | 功能說明 | | -------- | ---------------------------------- | | `axios` | 發送 HTTP 請求(`GET`, `POST`, `PUT` 等) | | `dotenv` | 讀取 `.env` 環境變數(後端 Express 用) | 📦 安裝指令: ```bash npm i axios npm i express dotenv # 若需要後端 ``` 🧠 建議搭配 `services/xxxService.js` 分工封裝,並使用 `try/catch` 處理錯誤。 --- ### ✅ 類別六:表單驗證與資料格式處理(僅《總覽》有提及) | 套件名稱 | 功能說明 | | ---------------------- | -------------------------------------- | | `vee-validate` + `yup` | 表單驗證組合:`yup` 定義 schema,`vee` 整合 Vue UI | | `dayjs` | 輕量版 `moment.js`,格式轉換、相對時間處理 | | `@iconify/vue` | 萬用圖示庫,可支援超過百種 icon 集合 | 📦 安裝指令(整包): ```bash npm i pinia pinia-plugin-persistedstate axios vee-validate yup dayjs @iconify/vue ``` --- ## 🔧 六、進階功能與懶人工具 × 動畫互動補充 📌 來源整合:〈指南〉 + 〈總覽〉 這些工具不是啟動專案的「必裝項」,但一旦畫面與檔案增加,就能大幅 **降低手動 import、元件註冊、路由設定、layout 切換** 的重複工作;另外,動畫與輪播套件讓畫面更有互動感。 --- ### 6-1 懶人工具四件組(Auto Import / Components / Router / Layouts) | 目標 | 套件 | 作用 | | ------------- | ------------------------------ | ---------------------------------- | | 自動引入函式 | `unplugin-auto-import` | 不用再手寫 `import { ref } from 'vue'` | | 自動註冊元件 | `unplugin-vue-components` | `/components`、PrimeVue 元件自動可用 | | 自動產生路由 | `unplugin-vue-router` | 掃描 `/src/pages` → 生成路由表 | | 自動套用頁面 Layout | `vite-plugin-vue-layouts-next` | 每個頁面用 `definePageMeta()` 指定 layout | 📦 一口氣安裝: ```bash npm i -D unplugin-auto-import unplugin-vue-components unplugin-vue-router vite-plugin-vue-layouts-next ``` #### Vite 設定範例(精簡版) ```js import { defineConfig } from 'vite' import Vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { PrimeVueResolver } from 'unplugin-vue-components/resolvers' import VueRouter from 'unplugin-vue-router/vite' import Layouts from 'vite-plugin-vue-layouts-next' import { VueRouterAutoImports } from 'unplugin-vue-router' export default defineConfig({ plugins: [ VueRouter(), // ① 自動路由 Layouts(), // ② 自動 layout Vue(), // ③ 解析 .vue 檔 Components({ // ④ 自動元件 resolvers: [PrimeVueResolver()], }), AutoImport({ // ⑤ 自動 import imports: [ 'vue', VueRouterAutoImports, // 把 router 方法也自動引入 { pinia: ['defineStore', 'storeToRefs'] }, ], vueTemplate: true, eslintrc: { enabled: true }, }), ], }) ``` > ✅ 只要 `/src/pages/about.vue` 存在,就會自動得到路由 `/about`; > ✅ `<Button>` 放在任意 `.vue`,插件會自動幫你 `import` 並註冊 PrimeVue 的 Button; --- ### 6-2 PrimeVue × Layouts × Router 實際配合流程 1. 在 `/src/layouts/` 建立 `default.vue`, `admin.vue`, `auth.vue` … 2. 在頁面元件 `<script setup>` 中加入: ```vue definePageMeta({ layout: 'admin' }) ``` 3. `vite-plugin-vue-layouts-next` 會自動包裝對應 layout。 --- ### 6-3 字體套件 - `unplugin-fonts` > Google Fonts 自動下載打包,避免 FOUC ```bash npm i -D unplugin-fonts ``` 在 `vite.config.js`: ```js import Fonts from 'unplugin-fonts/vite' Fonts({ google: { families: [{ name: 'Roboto', styles: 'wght@100;300;400;700' }] }, }) ``` --- ### 6-4 動畫/互動功能套件(來自〈總覽〉) | 套件 | 分類 | 用途亮點 | 適合情境 | | ------------ | ------ | ---------------------- | ---------------- | | **GSAP** | 動畫函式庫 | 功能最完整、效能佳、控制精細 | 頁面轉場、滾動觸發動畫、流程動畫 | | **Swiper** | 輪播工具 | loop / autoplay,行動裝置友善 | Banner、產品圖輪播 | | **Anime.js** | 輕量動畫工具 | 語法簡單,入門快速 | Icon 漂浮、數字遞增動畫 | 使用提醒: ```vue <script setup> import { Swiper, SwiperSlide } from 'swiper/vue' import 'swiper/css' import gsap from 'gsap' import { onMounted } from 'vue' onMounted(() => { gsap.to('.box', { x: 300, duration: 1 }) }) </script> ``` > *GSAP / Anime.js* 需等元件掛載完成再操作 DOM,建議寫在 `onMounted`。 > *Swiper* 記得引入 `/css`,並建議用 `swiper/vue` 元件版本。 --- ## 🧩 七、axios × Proxy × Express 串接整合實戰 📌 來源:〈總覽〉為主,補充整合《指南》簡版內容 🎯 教你從前端打 API → 經過 Proxy 轉發 → 到後端 Express 回傳資料的完整流程 --- ### 📦 7-1 問題背景:CORS 跨域錯誤是怎麼發生的? 假設: * Vue(Vite)跑在:`http://localhost:5173` * Express 跑在:`http://localhost:3000` 你在前端這樣寫: ```js axios.get('http://localhost:3000/api/hello') ``` 🚨 會出現錯誤: ``` ❌ Access to fetch at 'http://localhost:3000/api/hello' from origin 'http://localhost:5173' has been blocked by CORS policy ``` --- ### ✅ 7-2 解法:使用 Vite Proxy 轉發 API #### 📌 改寫 axios 請求(只寫 `/api/...`) ```js axios.get('/api/hello') ``` #### 📌 在 `vite.config.js` 加入 proxy 設定 ```js server: { proxy: { '/api': 'http://localhost:3000' } } ``` 這表示: > 「前端發送 `/api/xxx`,Vite 幫你偷偷轉送到 `http://localhost:3000/api/xxx`」 ✅ 避開跨域限制(CORS),前端不用知道後端在哪。 --- ### 🛠 7-3 Express 後端 API 範例(含 `.env`) 📁 `server/index.js` ```js import express from 'express' import dotenv from 'dotenv' dotenv.config() const app = express() const port = process.env.PORT || 3000 app.get('/api/hello', (req, res) => { res.json({ message: 'Hello from backend!' }) }) app.listen(port, () => { console.log(`✅ Server running at http://localhost:${port}`) }) ``` 📁 `.env` ```env PORT=3000 VITE_API_BASE_URL=http://localhost:3000 ``` --- ### 🔁 7-4 在前端使用 `.env` + axios 📁 `.env`: ```env VITE_API_BASE_URL=http://localhost:3000 ``` 📁 `services/userService.js`: ```js import axios from 'axios' const baseURL = import.meta.env.VITE_API_BASE_URL export const login = (formData) => axios.post(`${baseURL}/login`, formData) export const fetchUser = (id) => axios.get(`${baseURL}/user/${id}`) ``` --- ### ☂️ 7-5 加入 try/catch 與錯誤處理 ```js export const fetchUser = async (id) => { try { const res = await axios.get(`${baseURL}/user/${id}`) return res.data } catch (error) { console.error('❌ 無法取得使用者資料', error) throw error } } ``` --- ### 🛡️ 7-6 建立 axiosInstance(進階) 📁 `services/axiosInstance.js` ```js import axios from 'axios' const instance = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, }) // 自動附加 Token instance.interceptors.request.use((config) => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) export default instance ``` 之後就能改為這樣用: ```js import api from './axiosInstance' export const fetchUser = (id) => api.get(`/user/${id}`) ``` --- ### 🧭 7-7 多環境 Proxy 寫法 ```js const isDev = process.env.NODE_ENV === 'development' server: { proxy: { '/api': isDev ? 'http://localhost:3000' : 'https://your-prod-api.com' } } ``` --- ✅ 到這裡,你的前後端開發流程就能: ``` Vue 組件 → axios 發送 /api → Vite Proxy → Express 後端回應 JSON → 畫面更新 ``` --- ## 📚 八、結構補遺 × 建立時機 × 三方分工整理 📌 來源:〈總覽〉補充區段 🎯 整理零散但實用的概念與規則,方便查表與回顧 --- ### 🧱 8-1 各資料夾「建立時機」與啟用條件 | 資料夾 / 功能區 | 建立時機 or 什麼情況需要? | 備註 | | -------------- | ------------------------------------------- | --------------------------- | | `router/` | 安裝 `vue-router` 後(無論是手動還是自動路由) | 建立 `index.js` 並定義 routes | | `views/` | 一開始就需要,對應每個路由畫面 | 每個畫面一個 .vue | | `components/` | 實作畫面時會自然需要(按鈕、表單、卡片等) | 建議分類 + 對應 props/slots | | `plugins/` | 安裝任何 Plugin 後(如 PrimeVue, VeeValidate) | 把初始化邏輯集中收納 | | `store/` | 有跨元件 / 跨頁共用資料時(登入狀態、購物車等) | Pinia + plugin 註冊 | | `services/` | 只要開始呼叫 API,就應建立 | 每個功能模組一個 .js | | `composables/` | 出現多次共用邏輯時(如 useForm、useAuth、useQueryString) | 自定義 useXXX 函式區 | | `constants/` | 有固定選項、對照資料、狀態碼等時(如 select 選單) | 與邏輯分離,方便維護 | | `.env` | 有 baseURL、PORT、API key 等變數需求時 | `VITE_` 為前端變數前綴 | | `.gitignore` | 開專案第一天就該建立 | 避免上傳 node\_modules / .env 等 | --- ### 🧠 8-2 `views/` vs `components/` 差異表 | 比較項目 | `views/` | `components/` | | ---- | ------------------------- | ----------------------------------- | | 定位 | 路由對應的整頁畫面 | 可重用 UI 小模組 | | 用途 | `router-view` 顯示畫面 | 組合式拼圖,例如按鈕、欄位、Modal 等 | | 出現頻率 | 一個頁面一個 | 可多頁共用 | | 對應路徑 | 通常 `/src/views/PageX.vue` | 通常 `/src/components/ComponentX.vue` | --- ### 🎯 8-3 Vue × Vite × PrimeVue 三方分工表 | 功能語法 | 誰決定的? | 功能說明或設計邏輯 | | ---------------------------------------- | ---------- | -------------------------------- | | `createApp(App)` | Vue | Vue 應用的啟動方式 | | `.mount('#app')` | Vue | 掛載 Vue 應用至 HTML 畫面 | | `import App.vue` | Vue + Vite | Vite 支援 `.vue` 檔案模組解析 | | `import PrimeVue from 'primevue/config'` | PrimeVue | UI 套件初始化(需 `.use()` 註冊) | | `import 'primevue/resources/...` | PrimeVue | 樣式需手動引入才能生效(主題樣式、元件樣式、icon、排版工具) | | `import.meta.env.VITE_API_BASE_URL` | Vite | 前端讀取 `.env` 需加 `VITE_` 開頭 | | `vite.config.js` 中的 `plugins` | Vite | 所有插件整合的設定區,控制路由、元件註冊、自動 import 等 | --- ### 📘 8-4 小知識補充區 * 📂 Git 不會追蹤空資料夾,需放一個 `.gitkeep` 讓它保留結構 * 🔐 `.env` 不應上傳到 Git,因為通常包含敏感資訊 * 🔁 多環境 `.env.production` / `.env.development` Vite 會自動切換 * ⚙️ `defineConfig()` 是 Vite 的設定統一入口(對等於 webpack.config) --- ## 🧰 九、常駐功能型工具 × 專案中期常用套件 📌 來源:《總覽》功能分類區段 這些工具雖不是「初始化專案」就必裝,但只要專案一進入登入系統 / 資料傳輸 / 表單驗證等階段,幾乎都會出現,建議在「專案中期」評估導入。 --- ### 🧱 9-1 常駐型功能工具六件組 | 套件名稱 | 類型 | 適合使用時機 | 簡要說明 | | ----------------------------- | ------- | --------------------- | ------------------------------------ | | `pinia` | 狀態管理 | 有登入資訊 / 多頁共用資料需求時 | Vue 官方推薦的狀態管理工具,取代 Vuex | | `pinia-plugin-persistedstate` | 狀態儲存 | 登入狀態須保留(刷新不消失)時 | 可自動儲存到 localStorage 或 sessionStorage | | `axios` | HTTP 請求 | 只要要打 API 就需要 | 處理資料傳輸,配合 Vite Proxy 可避開 CORS | | `vee-validate` + `yup` | 表單驗證 | 有表單送出行為時(註冊、登入、填寫資料等) | `vee` 綁定欄位與規則、`yup` 設計規則架構 | | `dayjs` | 時間處理 | 需要顯示、運算、轉換日期時間時 | 輕量化的 moment.js 替代品 | | `@iconify/vue` | Icon 套件 | 有自訂 icon 或大量 icon 使用時 | 支援萬國圖示庫,可自由指定 icon name 使用 | --- ### 🛠 9-2 安裝範例與使用技巧 #### ✅ `pinia` × `persistedstate` 安裝與註冊 ```bash npm i pinia npm i pinia-plugin-persistedstate ``` 📁 `main.js` 註冊: ```js import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) app.use(pinia) ``` 📁 `store/user.js`: ```js import { defineStore } from 'pinia' export const useUserStore = defineStore('user', { state: () => ({ token: '', userData: {} }), persist: true }) ``` --- #### ✅ `vee-validate` × `yup` 表單驗證 ```bash npm i vee-validate yup ``` 📁 `components/LoginForm.vue`: ```vue <script setup> import { useForm, useField } from 'vee-validate' import * as yup from 'yup' const schema = yup.object({ email: yup.string().email().required(), password: yup.string().min(6).required() }) const { handleSubmit } = useForm({ validationSchema: schema }) const { value: email } = useField('email') const { value: password } = useField('password') const onSubmit = handleSubmit(values => { console.log('✅ 資料正確送出', values) }) </script> ``` --- #### ✅ `@iconify/vue` 安裝與使用 ```bash npm i @iconify/vue ``` ```vue <script setup> import { Icon } from '@iconify/vue' </script> <template> <Icon icon="mdi:home" /> </template> ``` > 查找 icon name 請至:[https://icones.js.org/](https://icones.js.org/) --- #### ✅ `dayjs` 常用範例 ```bash npm i dayjs ``` ```js import dayjs from 'dayjs' console.log(dayjs().format('YYYY-MM-DD')) console.log(dayjs('2025-07-09').fromNow()) ``` --- ### 📘 9-3 小結 * **pinia + persist** 處理登入資訊與跨頁共用狀態 * **axios** 處理 API 串接、可配合 token 注入 * **vee + yup** 為驗證表單提供強大支援 * **dayjs** 操作時間超直覺 * **iconify** 萬用 icon 套件,不再被框在特定 UI 套件中 --- ## 🎞️ 十、動畫與展示強化工具總覽 📌 來源:〈總覽〉功能工具補充區 🎯 畫面動態、過場動畫、輪播展示等互動功能,需仰賴額外 UI 工具或動畫函式庫支援。這些套件常見於 Landing Page、行銷頁、圖文輪播區等。 --- ### 🎬 10-1 三大動畫函式庫與用途對照 | 套件名稱 | 適合使用時機 | 特性簡介 | | ---------- | ---------------------- | ------------------ | | `gsap` | 時間軸動畫、進場特效、滾動動畫等 | 極強大動畫控制函式庫,可製作精緻動畫 | | `anime.js` | 精緻 SVG / Canvas 動畫 | 精準控制動畫屬性,可做細節微動畫 | | `AOS` | 卷軸動畫(scroll reveal 效果) | 畫面滑入滑出動畫的懶人套件,效果簡潔 | --- ### 🎠 10-2 三大圖文輪播工具比較 | 套件名稱 | 使用場景 | 特性或優缺點備註 | | --------------- | --------- | ---------------------------- | | `swiper` | 輪播圖、卡片滑動區 | 功能完整、社群活躍,支援觸控滑動,設計彈性高 | | `vue3-carousel` | 簡單輪播需求 | 輕量好用,語法簡單,適合初學者 | | `splide` | 特殊輪播效果 | 支援 vertical slide、fade 等多種模式 | > 📌 若已使用 PrimeVue,內建 `Carousel` 元件也可用來展示清單型圖片卡片。 --- ### ⚙️ 10-3 安裝與基本使用範例(以 `swiper` 為例) ```bash npm i swiper ``` 📁 `components/ImageSwiper.vue`: ```vue <script setup> import { Swiper, SwiperSlide } from 'swiper/vue' import 'swiper/css' </script> <template> <Swiper :slides-per-view="1" loop autoplay> <SwiperSlide v-for="i in 3" :key="i"> <img :src="`/img/banner-${i}.jpg`" /> </SwiperSlide> </Swiper> </template> ``` --- ### 🎯 10-4 元件設計搭配建議 * ✨ 如果追求 **動畫精緻度、流程控制**:用 `gsap` + 時間軸 * 🌀 如果希望 **快速套用卷軸出現效果**:用 `AOS` + class 套件 * 📷 如果需要 **展示圖片/滑動卡片區塊**:用 `swiper` 或內建 `Carousel` --- ### 🧩 10-5 實務小撇步 * 動畫請酌量使用,不建議所有元件都加動畫 → 容易疲勞+效能負擔 * 多數動畫函式庫不會主動移除效果,切換頁面記得清除 / dispose * 若使用 `keep-alive`,動畫效果與 hook 行為可能出現異常,需注意設計順序 --- ## 🗂 十一、Vue 專案骨架 × 資料夾職責地圖 📌 來源:《總覽》中段「專案目錄與邏輯結構總覽」段落 🎯 幫助你快速掌握每個資料夾的作用、建立時機、典型內容與命名慣例 --- ### 📂 11-1 Vue × Vite 專案資料夾一覽圖(文字化版本) ``` 📦 /src ├── 📁 assets → 靜態圖片、圖示、icon(非 components 圖示) ├── 📁 components → 可重複元件(按鈕、欄位、彈窗、卡片) ├── 📁 views → 路由對應畫面(每頁一個) ├── 📁 layouts → 導覽列、頁面框架、Layout 組合結構 ├── 📁 router → 路由設定(Vue Router)+ routes 對應表 ├── 📁 store → pinia 狀態管理(登入資訊、跨頁資料) ├── 📁 plugins → 各類 Plugin 初始化與註冊(如 PrimeVue、axios) ├── 📁 services → API 封裝與資料存取邏輯(axios + baseURL) ├── 📁 composables → 共用邏輯(useXXX),與元件無關的邏輯模組 ├── 📁 styles → SCSS 或全域樣式檔(含 Reset、變數、佈局等) ├── 📁 constants → 常數對照表、狀態碼、下拉選單選項等固定資料 ├── 📁 data → 假資料 / 測試資料(不進行 fetch) ├── 📁 directives → 自定義 Vue 指令(v-focus, v-intersect 等) ├── 📄 main.js → 程式主入口:App 啟動、Plugin 註冊等 ├── 📄 App.vue → App 框架主元件(通常只放 router-view) ``` --- ### 🧭 11-2 資料夾職責 × 功能分工一覽表 | 資料夾名稱 | 職責定位 | 典型內容與建議 | 建立時機 | | -------------- | ---------------- | --------------------------------- | --------------- | | `views/` | 路由對應畫面(每頁一個) | PageA.vue、PageB.vue | 安裝 Vue Router 後 | | `components/` | 共用元件區,重複使用的 UI | InputField.vue、Modal.vue | 開始畫面開發時 | | `layouts/` | Layout 樣板,提供頁面骨架 | DefaultLayout.vue、AdminLayout.vue | 頁面區分明顯或有固定框架時 | | `router/` | 路由總表與 route 模組 | index.js、routes 資料夾 | 安裝 Vue Router 後 | | `store/` | 狀態儲存與共用資料 | user.js、cart.js、auth.js | 有登入或跨頁資料需求時 | | `services/` | API 操作封裝(axios) | userService.js、orderService.js | 要串接後端 API 時 | | `composables/` | 共用邏輯(自定義 Hook) | useForm.js、useAuth.js | 多次重複的邏輯出現時 | | `plugins/` | 插件初始化設定 | veeValidate.js、primevue.js | 安裝任何 Plugin 套件後 | | `constants/` | 常數表 / 對照資料 | statusMap.js、dropdownOptions.js | 下拉選單、狀態碼出現時 | | `styles/` | 樣式相關 | base.scss、reset.css、theme.css | 使用 SCSS 或設計系統時 | | `data/` | 模擬資料(非 fetch) | mockUser.json、staticTable.js | 尚無後端資料、先行測試用 | | `directives/` | 自定義指令 | v-focus.js、v-intersect.js | 有特殊 DOM 行為需求時 | --- ### 🧠 11-3 補充觀念 × 建議命名策略 * ✅ 檔案名建議使用 **小駝峰** 或 **首字大寫** 規則(如:`LoginPage.vue` / `userService.js`) * ✅ 資料夾內若超過 5 個以上 .vue/.js 建議分子資料夾(by 主題 or by 模組) * ✅ 可以加 `.gitkeep` 保留空資料夾結構,避免被 Git 忽略 --- ### 📌 小提醒:不要亂混分類! | 錯誤例子 | 改進方式 | | ------------------ | ----------------------------- | | 把 API 寫在元件內 | 拆出去放在 `services/` | | 把登入狀態寫在 props 傳來傳去 | 使用 `pinia` 或 inject / provide | | 把 layout 跟頁面綁在一起 | 抽出 layout 檔案,讓 views 更乾淨 | | 所有東西都寫一頁沒拆開 | 模組化各功能,維持可維護性與可讀性 | --- ## 📄 附錄:`main.js` 流程逐行說明 × 啟動邏輯全解 📌 來源:《總覽》最尾段補充 🎯 幫助你理解 Vue + Vite 專案從 `main.js` 啟動時,實際發生了什麼事,哪些是必要的、哪些是套件設定。 --- ### 🪜 啟動流程概觀(初始化順序) 1. 匯入 Vue 套件與 App 主元件 2. 建立應用程式實體 3. 註冊各種 Plugin(如 Pinia、Router、PrimeVue) 4. 掛載到 HTML 頁面 --- ### 🔍 每行說明範例 📁 `main.js`(典型格式): ```js import { createApp } from 'vue' // 匯入 Vue 主功能 import App from './App.vue' // 匯入整個應用的最外層元件 import router from './router' // 匯入路由設定 import PrimeVue from 'primevue/config' // 引入 UI 套件 import { createPinia } from 'pinia' // 狀態管理工具 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' // 狀態儲存插件 import './styles/main.scss' // 匯入全域樣式 import 'primevue/resources/themes/aura-light-green/theme.css' // 主題樣式 import 'primeicons/primeicons.css' // PrimeVue 專用圖示 import 'primevue/resources/primevue.min.css' // PrimeVue 核心樣式 const app = createApp(App) // 建立 Vue 應用 const pinia = createPinia() // 建立 Pinia 實體 pinia.use(piniaPluginPersistedstate) // 注入 plugin 功能 app.use(router) // 掛載 Vue Router app.use(pinia) // 掛載 Pinia app.use(PrimeVue) // 掛載 PrimeVue(還可設定 config) app.mount('#app') // 掛載到 HTML 中的 <div id="app"> ``` --- ### 🧠 延伸知識補充 | 對象 | 功能說明與使用時機 | | ---------------------- | -------------------------------------- | | `createApp(App)` | 建立 Vue 應用的入口點,是一切邏輯的起點 | | `app.use(...)` | 注入各種外部功能,如路由、UI 套件、狀態管理等 | | `app.mount('#app')` | 將 Vue 接手渲染控制 `<div id="app">` 中的內容 | | `App.vue` | 整個畫面的最外層元件,通常只有 layout 與 `router-view` | | `import './styles/...` | 所有樣式檔案與資源(SCSS、icon、外部主題)需明確載入 | --- ### ⚠️ 常見錯誤與除錯提醒 | 問題訊息 | 常見原因 | | ------------------------------------- | -------------------------------- | | `Cannot read properties of undefined` | Plugin 使用順序錯誤,或未 `.use()` | | 畫面無樣式 | 忘記引入 PrimeVue 主題 / 核心 CSS | | 路由跳轉無效 | 忘記 `app.use(router)` 或路由檔案路徑錯誤 | | 頁面刷新狀態消失 | 忘記使用 `piniaPluginPersistedstate` | --- ### ✅ 小結與實務建議 * 建議將 `main.js` 統一作為初始化中心,不要把 Plugin 直接放在其他地方引入,便於管理與閱讀 * 若邏輯複雜,可拆分為:`main.js` + `plugins/index.js` 統整 Plugin 註冊 * 若有多組樣式檔,可集中在 `/styles/main.scss` 統一引入,避免漏掉 --- ## 🧩 十二、進階設定 × 問題排解 × 套件工具包 📌 來源:《總覽》遺漏補遺 × 輔助工具與除錯技巧 🎯 整合常見的設定技巧、開發過程中好用的輔助工具、以及報錯排解小抄,幫助你在實務開發中更穩定地前進。 --- ### 🌐 12-1 Proxy 跨域設定 × API 重導技巧 📦 用途:避免 `CORS` 錯誤,前端模擬請求真實後端 API。 ```js // vite.config.js export default defineConfig({ server: { proxy: { '/api': { target: 'https://your-backend-server.com', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } } }) ``` | 設定項 | 說明 | | -------------- | --------------------------------- | | `target` | 你要導向的真實 API 網址 | | `changeOrigin` | 是否修改來源標頭為目標主機(預設為 false) | | `rewrite` | 重寫路徑:將 `/api/xxx` 改成 `/xxx` 發送到後端 | > ⚠️ 若未設定 rewrite,後端若不接受 `/api` 前綴可能會出錯。 --- ### 🛠 12-2 開發輔助插件清單 × 自動化工具 | 套件名稱 | 功能 | 安裝方式 | | ------------------------- | ----------------------------------------- | ---------------------------------- | | `unplugin-auto-import` | 自動導入常用函式(如 `ref`, `computed`) | `npm i -D unplugin-auto-import` | | `unplugin-vue-components` | 自動註冊元件 | `npm i -D unplugin-vue-components` | | `unplugin-vue-router` | 自動掃描 pages,生成 routes | `npm i -D unplugin-vue-router` | | `vite-plugin-pages` | 對應資料夾自動生成頁面路由 | `npm i -D vite-plugin-pages` | | `vite-plugin-inspect` | Vite 插件可視化(開 `localhost:5173/__inspect/`) | `npm i -D vite-plugin-inspect` | 🔧 使用這些插件能省下許多樣板程式碼,減少錯誤與重複工作,建議在中型以上專案就導入。 --- ### 🎨 12-3 PrimeVue 樣式設定 × 主題選擇小技巧 ```js // main.js 範例 import 'primevue/resources/themes/aura-light-green/theme.css' import 'primevue/resources/primevue.min.css' import 'primeicons/primeicons.css' ``` | 樣式檔 | 功能說明 | | ------------------ | ---------------------------- | | `theme.css` | 主題樣式:需選擇一種(Aura 系列、Lara 系列等) | | `primevue.min.css` | 核心樣式(按鈕、表單等通用 UI) | | `primeicons.css` | Prime 專屬圖示字型 | ✅ 主題選擇建議從 [官方主題列表](https://primevue.org/theming/#themes) 中挑選一套風格一致的來使用。 --- ### 💻 12-4 VSCode 建議設定 × 開發效率加速器 | 工具 / 檔案 | 說明與建議 | | ----------------------- | ----------------- | | `Volar` | Vue 官方推薦的語言支援擴充 | | `Prettier` | 統一程式碼格式 | | `ESLint` | 靜態程式碼檢查工具,找出潛在錯誤 | | `.vscode/settings.json` | 可共用的團隊統一格式與快捷鍵設定檔 | 📁 `.vscode/settings.json` 範例: ```json { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "eslint.validate": ["javascript", "vue"] } ``` --- ### 🔍 12-5 安裝錯誤 × 執行錯誤對應小抄 | 錯誤訊息 | 原因與解法建議 | | -------------------------------------------- | ----------------------------- | | `ERR_MODULE_NOT_FOUND` | 模組路徑錯誤,檔案名拼錯 / 忘了副檔名 | | `Cannot read properties of undefined` | 插件順序錯誤 / 資料未定義 / 初始化錯誤 | | `vite not found` / `vite: command not found` | 忘記安裝 Vite(執行 `npm i vite -D`) | | `SyntaxError: Unexpected token` | 通常為語法錯誤,或 JSON 格式錯誤 | | 畫面沒樣式 | 忘記引入主題 CSS 或順序錯誤 | --- ### 🧪 12-6 Node.js / npm 版本建議 × 環境建置 | 工具 | 推薦版本 | 說明 | | ------- | ----------- | -------------------- | | Node.js | 18.x(LTS 版) | 穩定、安全、套件相容性高 | | npm | 9.x 或更新版本 | 與 Node.js 版本自動綁定 | | nvm | 最新版 | 多版本切換工具,推薦安裝開發多專案時使用 | 🧭 可使用命令確認版本: ```bash node -v npm -v ```