refactor(login): compose page from focused login components
Split the login page into smaller reusable components for branding, toolbar, header, form, announcements, and mobile layout behavior. This keeps the view responsible for orchestration while moving UI sections into focused components. Update page creation docs to reflect the simplified flow where views render sections/items directly and composables coordinate store/service access when needed.refactor(login): compose page from focused login components Split the login page into smaller reusable components for branding, toolbar, header, form, announcements, and mobile layout behavior. This keeps the view responsible for orchestration while moving UI sections into focused components. Update page creation docs to reflect the simplified flow where views render sections/items directly and composables coordinate store/service access when needed.
This commit is contained in:
@@ -7,9 +7,9 @@
|
||||
目前新增一般頁面的預設資料流:
|
||||
|
||||
```txt
|
||||
router -> view -> (page driver) -> page component -> sections/items
|
||||
↓
|
||||
store/composable -> service
|
||||
router -> view -> sections/items
|
||||
↓
|
||||
composable -> store -> service
|
||||
```
|
||||
|
||||
Page driver 不是必備層:若頁面邏輯只有簡單的 `computed` page model(無搜尋、無 dialog、無複雜事件協調),直接在 view 裡寫即可,不需要建立 page driver。
|
||||
@@ -22,7 +22,6 @@ Page driver 不是必備層:若頁面邏輯只有簡單的 `computed` page mod
|
||||
<!-- src/views/reports/Reports.vue -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import PageReports from '@/components/pages/PageReports.vue'
|
||||
import { useSnackbarStore } from '@/stores/snackbar'
|
||||
|
||||
export interface ReportSummary {
|
||||
@@ -55,54 +54,9 @@ function openReport(row: ReportSummary) {
|
||||
|
||||
若頁面需要協調多個 composable(搜尋、表單、CRUD flow、dialog 狀態),才建立 page driver。page driver 的慣例見 `src/composables/GUIDE.md`。
|
||||
|
||||
## 2. 新增 page component
|
||||
|
||||
完整頁面主畫面放在 `src/components/pages`,檔名使用 `Page` 前綴。component 以 props 接收資料,以 emit 回報使用者事件,不直接處理 route 或底層 HTTP。
|
||||
|
||||
```vue
|
||||
<!-- src/components/pages/PageReports.vue -->
|
||||
<script setup lang="ts">
|
||||
import type { ReportSummary } from '@/views/reports/Reports.vue'
|
||||
|
||||
defineProps<{
|
||||
page: { title: string; rows: ReportSummary[] }
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
open: [row: ReportSummary]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card flat>
|
||||
<v-card-title class="text-h6">{{ page.title }}</v-card-title>
|
||||
<v-table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名稱</th>
|
||||
<th>負責單位</th>
|
||||
<th class="text-right">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in page.rows" :key="row.id">
|
||||
<td>{{ row.title }}</td>
|
||||
<td>{{ row.owner }}</td>
|
||||
<td class="text-right">
|
||||
<v-btn color="primary" size="small" variant="text" @click="emit('open', row)">
|
||||
開啟
|
||||
</v-btn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-table>
|
||||
</v-card>
|
||||
</template>
|
||||
```
|
||||
|
||||
若畫面是固定的「篩選條件 + 查詢按鈕 + 結果表格」,優先使用 `components/sections/SectionQueryPage.vue`。若是「表單欄位 + 送出/存檔按鈕」,優先使用 `components/sections/SectionFormPage.vue`。
|
||||
|
||||
## 3. 加入 route
|
||||
## 2. 加入 route
|
||||
|
||||
route 加在 `src/router/routes.ts` 的 `routes` 陣列中,並放在 `/:pathMatch(.*)*` catch-all route 前面。
|
||||
|
||||
@@ -125,7 +79,7 @@ route 加在 `src/router/routes.ts` 的 `routes` 陣列中,並放在 `/:pathMa
|
||||
- 新功能若使用後端選單,優先調整後端選單資料或對應 API mock,不要把頁面專屬選單邏輯塞進 layout。
|
||||
- 若只是新增 route,通常不需要修改 `MainLayout.vue` 或 `src/shell/*`。
|
||||
|
||||
## 4. 需要 API 時新增 service module
|
||||
## 3. 需要 API 時新增 service module
|
||||
|
||||
```ts
|
||||
// src/services/modules/reports.ts
|
||||
@@ -148,7 +102,7 @@ service 只封裝 HTTP 細節,不持有 UI 狀態。
|
||||
|
||||
`httpClient` 的 `baseURL` 來自 `VITE_API_BASE_URL`,沒有設定時預設 `/service/api`。開發模式下,Vite proxy 會將 `/service/*` 轉送到 `VITE_PROXY_TARGET`。
|
||||
|
||||
## 5. 需要共享狀態時新增 store
|
||||
## 4. 需要共享狀態時新增 store
|
||||
|
||||
只有跨頁共享、需要快取、或全域狀態才新增 store。單頁暫時狀態留在 view、component 或 composable。
|
||||
|
||||
@@ -180,7 +134,7 @@ export const useReportsStore = defineStore('reports', () => {
|
||||
})
|
||||
```
|
||||
|
||||
## 6. 驗證
|
||||
## 5. 驗證
|
||||
|
||||
至少執行:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user