# 新增頁面範例 這份文件示範如何用目前 `src/` 慣例新增一個被 `MainLayout` 包住的一般功能頁。 範例功能:`reports` ## 1. 新增 route view ```vue ``` view 的責任是頁面資料組裝與事件協調。畫面區塊交給 feature component。 ## 2. 新增 feature component ```vue ``` component 以 props 接收資料,以 emit 回報事件。不要在 component 裡直接處理 route 或底層 HTTP。 ## 3. 加入 route route 加在 `src/router/routes.ts` 的 `routes` 陣列中,並放在 `/:pathMatch(.*)*` catch-all route 前面。 ```ts // src/router/routes.ts { path: '/reports', name: 'reports', component: () => import('@/views/reports/Reports.vue'), meta: { layout: 'default', requiresAuth: true }, } ``` `layout: 'default'` 會讓頁面被 `MainLayout` 包住。登入頁、錯誤頁、維護中頁才使用 `layout: 'none'`。 若頁面需要出現在 drawer menu、favorites 或 breadcrumb: - menu 來源目前由 `src/stores/menu.ts` 轉換後端選單資料。 - breadcrumb 會依 route path、menu/favorite items 與 fallback title 產生。 - 新功能若使用後端選單,優先調整後端選單資料或對應 API mock,不要把頁面專屬選單邏輯塞進 layout。 - 若只是新增 route,通常不需要修改 `MainLayout.vue`。 ## 4. 需要 API 時新增 service module ```ts // src/services/modules/reports.ts import { httpClient } from '../client' export interface ReportSummary { id: number title: string owner: string } export const reportsApi = { list: () => httpClient.get('/Reports'), } ``` service 只封裝 HTTP 細節,不持有 UI 狀態。 `httpClient` 的 `baseURL` 來自 `VITE_API_BASE_URL`。template 預設值見 `.env.example`,通常使用 `/service/api` 搭配 Vite proxy。 ## 5. 需要共享狀態時新增 store ```ts // src/stores/reports.ts import { defineStore } from 'pinia' import { ref } from 'vue' import { reportsApi, type ReportSummary } from '@/services/modules/reports' export const useReportsStore = defineStore('reports', () => { const items = ref([]) const loading = ref(false) const load = async () => { loading.value = true try { const { data } = await reportsApi.list() items.value = data } finally { loading.value = false } } return { items, loading, load, } }) ``` 只有跨頁共享、需要快取、或全域狀態才新增 store。單頁暫時狀態留在 view、component 或 composable。 ## 6. 驗證 至少執行: ```bash pnpm type-check pnpm build ``` 若有 route、layout 或主要互動流程變更,再啟動 dev server 並用瀏覽器確認。