fix: docing
This commit is contained in:
+167
-198
@@ -2,17 +2,17 @@
|
||||
|
||||
## 目的
|
||||
|
||||
這份文件只描述目前 repo 已經落地的前端分層與命名規則,讓後續新增檔案、搬移檔案、或重構時有一致判斷基準。
|
||||
這份文件描述目前 repo 已經落地的前端分層與命名規則,讓後續新增檔案、搬移檔案或重構時有一致判斷基準。
|
||||
|
||||
本文件是現況快照;新增功能與重構的細節規範以 `docs/architecture-strategy.md`、`docs/llm-development-guide.md` 與各層 `src/**/GUIDE.md` 為準。
|
||||
|
||||
目前專案的主要責任鏈如下:
|
||||
|
||||
- `router` 決定 route 與 layout meta
|
||||
- `App.vue` 根據 route meta 組裝 app shell 與全域 UI
|
||||
- `views` 承接路由入口與頁面資料協調
|
||||
- `components` 承接 layout、page component、domain component 與較細的 UI 區塊
|
||||
- `composables` 承接可重用流程與 UI state
|
||||
- `stores` 承接跨頁狀態、快取與全域顯示狀態
|
||||
- `services` 承接 HTTP client、API 模組、token 與錯誤處理
|
||||
```txt
|
||||
router -> App.vue -> AppShell -> layout -> view -> page component -> section -> item
|
||||
↓
|
||||
page driver / command composable -> store -> service
|
||||
```
|
||||
|
||||
## 目前目錄的責任邊界
|
||||
|
||||
@@ -26,93 +26,117 @@
|
||||
|
||||
責任:
|
||||
|
||||
- 定義 route 與 route meta
|
||||
- 指定頁面使用哪種 layout
|
||||
- 串接導航守衛
|
||||
- 定義 route 與 route meta。
|
||||
- 指定頁面使用哪種 layout。
|
||||
- 串接導航守衛。
|
||||
|
||||
目前 `meta.layout` 已是 app shell 切換的正式入口:
|
||||
目前 `meta.layout` 是 app shell 切換的正式入口:
|
||||
|
||||
- `default` 走 [MainLayout.vue](../src/components/layouts/MainLayout.vue)
|
||||
- `none` 走 [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)
|
||||
- `default` 走 [MainLayout.vue](../src/components/layouts/MainLayout.vue)。
|
||||
- `none` 走 [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)。
|
||||
|
||||
### `src/App.vue`
|
||||
### `src/App.vue` 與 `src/shell`
|
||||
|
||||
[App.vue](../src/App.vue) 目前不是單純掛載入口,而是實際的應用組裝層。
|
||||
[App.vue](../src/App.vue) 目前只掛載 [AppShell.vue](../src/shell/AppShell.vue),不再直接承擔全域 UI 組裝。
|
||||
|
||||
目前承擔的責任包含:
|
||||
`src/shell` 是 App Shell 層:
|
||||
|
||||
- 根據 `route.meta.layout` 切換 layout
|
||||
- 組裝 breadcrumb / favorites / menu 等 layout props
|
||||
- 放置全域搜尋結果 dialog
|
||||
- 放置全域訊息中心 dialog
|
||||
- 放置全域 snackbar
|
||||
- 串接 layout event 與路由跳轉
|
||||
- [AppShell.vue](../src/shell/AppShell.vue):layout 切換、layout props/events、breadcrumb actions、tabs router-view 與 `GlobalOverlays` 掛載。
|
||||
- [AppTabs.vue](../src/shell/AppTabs.vue):default layout 下的 tabs 與 keep-alive router-view 容器。
|
||||
- [GlobalOverlays.vue](../src/shell/GlobalOverlays.vue):全域 snackbar、搜尋 dialog、訊息 dialog。
|
||||
|
||||
判斷原則:
|
||||
|
||||
- 與整個 app shell 共享、且不屬於單一路由頁面的 UI,可留在 `App.vue`
|
||||
- 只屬於單一路由頁面的對話框或互動,不應堆到 `App.vue`
|
||||
- 與整個 app shell 共享、且不屬於單一路由頁面的 UI,可放在 `src/shell`。
|
||||
- 只屬於單一路由頁面的對話框或互動,不應放進 `src/shell`。
|
||||
- shell 狀態協調優先放在 `src/composables/layout/useAppShell.ts`。
|
||||
|
||||
### `src/views`
|
||||
|
||||
`views` 目前整體方向是「路由入口 + 頁面資料協調 + 頁面事件協調」。
|
||||
`views` 是 route entry,方向是薄層:呼叫 page driver、掛載 page component、協調 route-level 事件。
|
||||
|
||||
目前較薄的 view:
|
||||
目前較典型的薄 view:
|
||||
|
||||
- [Home.vue](../src/views/Home.vue)
|
||||
- [Login.vue](../src/views/Login.vue)
|
||||
- [EditableGrid.vue](../src/views/maint/EditableGrid.vue)
|
||||
- [Forbidden.vue](../src/views/errors/Forbidden.vue)
|
||||
- [ServerError.vue](../src/views/errors/ServerError.vue)
|
||||
- [ServiceUnavailable.vue](../src/views/errors/ServiceUnavailable.vue)
|
||||
- [NetworkError.vue](../src/views/errors/NetworkError.vue)
|
||||
- [Maintenance.vue](../src/views/errors/Maintenance.vue)
|
||||
- [NotFound.vue](../src/views/errors/NotFound.vue)
|
||||
- [ErrorShell.vue](../src/views/errors/ErrorShell.vue)
|
||||
- [FncPage.vue](../src/views/FncPage.vue)
|
||||
- [Settings.vue](../src/views/Settings.vue)
|
||||
|
||||
目前仍偏厚的 view:
|
||||
|
||||
- [FncPage.vue](../src/views/FncPage.vue)
|
||||
- [SingleRecord.vue](../src/views/maint/SingleRecord.vue)
|
||||
- [EditableGrid.vue](../src/views/maint/EditableGrid.vue)
|
||||
- [MasterDetailA.vue](../src/views/maint/MasterDetailA.vue)
|
||||
- [MasterDetailB.vue](../src/views/maint/MasterDetailB.vue)
|
||||
- [MasterDetailC.vue](../src/views/maint/MasterDetailC.vue)
|
||||
|
||||
錯誤頁集中在 `src/views/errors`,通常使用 `meta.layout = 'none'`,並由 [ErrorShell.vue](../src/views/errors/ErrorShell.vue) 共用錯誤頁骨架。
|
||||
|
||||
[Login.vue](../src/views/Login.vue) 是 template core 例外:它仍負責登入頁組合、功能開關、小型提示 dialog 與登入流程協調。登入頁 UI 拆在 `components/login/*`,captcha 與 announcement 流程拆在頂層 login composable。
|
||||
|
||||
`views` 應遵守的原則:
|
||||
|
||||
- 可以持有 route、store、頁面資料組裝、頁面事件協調
|
||||
- 可以管理只屬於該頁的 dialog 顯示狀態
|
||||
- 不應長期承擔大量可抽出的模板片段
|
||||
- 不應把可重用流程直接留在頁面內重複複製
|
||||
- 可以持有 route、page driver 掛載、頁面資料組裝與頁面事件協調。
|
||||
- 可以管理只屬於該頁的小型 dialog 顯示狀態。
|
||||
- 不應長期承擔大型表格、表單、dialog 模板或可重用流程。
|
||||
- 不應直接處理底層 HTTP 細節。
|
||||
|
||||
### `src/components`
|
||||
|
||||
目前 `components` 已經分成幾種不同角色,不能再用單一規則描述。
|
||||
`components` 依角色分層,不再用單一規則描述。
|
||||
|
||||
#### 1. 頁面型元件
|
||||
#### 1. Root page/template components
|
||||
|
||||
目前以下元件實際上扮演 page component:
|
||||
目前仍放在 `src/components` 根目錄的頁面外殼:
|
||||
|
||||
- [PageLogin.vue](../src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](../src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
|
||||
這些檔案的責任是:
|
||||
這些是既有 template 頁面外殼或登入頁組裝元件。新增一般功能頁時,優先使用 `src/components/pages`。
|
||||
|
||||
- 接收 view 組好的資料與事件
|
||||
- 組裝某個完整頁面的主畫面
|
||||
- 再往下使用較小的子元件或 domain component
|
||||
#### 2. `components/pages`
|
||||
|
||||
命名規則:
|
||||
`components/pages` 是完整頁面主畫面組裝層:
|
||||
|
||||
- 只要是 page component,檔名以 `Page` 為前綴
|
||||
- page component 可以放在 `components` 根目錄
|
||||
- 不要把 page component 丟進 `base`
|
||||
- [PageHome.vue](../src/components/pages/PageHome.vue)
|
||||
- [PageSettings.vue](../src/components/pages/PageSettings.vue)
|
||||
- [PageFunction.vue](../src/components/pages/PageFunction.vue)
|
||||
- [PageMaintenance.vue](../src/components/pages/PageMaintenance.vue)
|
||||
- [PageEditableGridMaintenance.vue](../src/components/pages/PageEditableGridMaintenance.vue)
|
||||
- [PageMasterDetailAMaintenance.vue](../src/components/pages/PageMasterDetailAMaintenance.vue)
|
||||
- [PageMasterDetailBMaintenance.vue](../src/components/pages/PageMasterDetailBMaintenance.vue)
|
||||
- [PageMasterDetailCMaintenance.vue](../src/components/pages/PageMasterDetailCMaintenance.vue)
|
||||
|
||||
#### 2. `components/login`
|
||||
責任:
|
||||
|
||||
登入頁的較細 UI 區塊已集中到:
|
||||
- 接收 view/page driver 組好的資料與事件。
|
||||
- 組裝完整頁面的主要 section 順序。
|
||||
- 再往下使用 sections、items、feature/domain components。
|
||||
|
||||
#### 3. `components/sections`
|
||||
|
||||
`components/sections` 是頁面區塊容器:
|
||||
|
||||
- [SectionSearchPanel.vue](../src/components/sections/SectionSearchPanel.vue)
|
||||
- [SectionDataTable.vue](../src/components/sections/SectionDataTable.vue)
|
||||
- [SectionFormPanel.vue](../src/components/sections/SectionFormPanel.vue)
|
||||
- [SectionFormPage.vue](../src/components/sections/SectionFormPage.vue)
|
||||
- [SectionQueryPage.vue](../src/components/sections/SectionQueryPage.vue)
|
||||
|
||||
責任:
|
||||
|
||||
- 決定區塊布局與區塊互動。
|
||||
- 以 props 接收資料,以 emit 回報事件。
|
||||
- 不知道 route,不直接呼叫 API。
|
||||
|
||||
#### 4. `components/items`
|
||||
|
||||
`components/items` 是欄位群組或單筆資料呈現層:
|
||||
|
||||
- [ItemFormFieldGroup.vue](../src/components/items/ItemFormFieldGroup.vue)
|
||||
|
||||
item 不應知道自己被放在表格、grid、dialog 或頁面哪個位置。
|
||||
|
||||
#### 5. `components/login`
|
||||
|
||||
登入頁的較細 UI 區塊集中在:
|
||||
|
||||
- [CreateAccountLink.vue](../src/components/login/CreateAccountLink.vue)
|
||||
- [LoginAnnouncementBoard.vue](../src/components/login/LoginAnnouncementBoard.vue)
|
||||
@@ -123,56 +147,12 @@
|
||||
- [LoginToolBar.vue](../src/components/login/LoginToolBar.vue)
|
||||
- [LoginVerify.vue](../src/components/login/LoginVerify.vue)
|
||||
|
||||
這一層的定位是:
|
||||
這一層服務 `PageLogin`,不是全域 base library。
|
||||
|
||||
- 服務 `PageLogin`
|
||||
- 屬於 login 頁面家族
|
||||
- 不是全域 base library
|
||||
#### 6. `components/maint`
|
||||
|
||||
#### 3. `components/base`
|
||||
`components/maint` 是 maintenance demo / domain component 區域:
|
||||
|
||||
目前 `components/base` 只剩下:
|
||||
|
||||
- [DraggableDialog.vue](../src/components/base/DraggableDialog.vue)
|
||||
|
||||
目前判斷原則很直接:
|
||||
|
||||
- `base` 只放真正可跨頁重用、且不屬於特定 domain 的元件
|
||||
- 若元件只服務單一頁面家族或單一 domain,優先放回對應資料夾
|
||||
|
||||
#### 4. `components/layouts`
|
||||
|
||||
目前 layout 實作集中於:
|
||||
|
||||
- [MainLayout.vue](../src/components/layouts/MainLayout.vue)
|
||||
- [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)
|
||||
- `src/components/layouts/main-layout/*`
|
||||
|
||||
其中 `main-layout/*` 是 `MainLayout` 底下拆出的骨架子元件:
|
||||
|
||||
- [AppBarBreadcrumbCol.vue](../src/components/layouts/main-layout/AppBarBreadcrumbCol.vue)
|
||||
- [AppBarFavoritesCol.vue](../src/components/layouts/main-layout/AppBarFavoritesCol.vue)
|
||||
- [AppBarTopCol.vue](../src/components/layouts/main-layout/AppBarTopCol.vue)
|
||||
- [DrawerDesktopMenu.vue](../src/components/layouts/main-layout/DrawerDesktopMenu.vue)
|
||||
- [DrawerMobileFavoritesPanel.vue](../src/components/layouts/main-layout/DrawerMobileFavoritesPanel.vue)
|
||||
- [DrawerMobileMenuPanel.vue](../src/components/layouts/main-layout/DrawerMobileMenuPanel.vue)
|
||||
|
||||
layout 應只承擔:
|
||||
|
||||
- app shell
|
||||
- drawer / app bar / favorites / breadcrumb 等框架 UI
|
||||
- 與 layout 視覺結構直接相關的互動
|
||||
|
||||
layout 不應承擔:
|
||||
|
||||
- 頁面專屬業務流程
|
||||
- 特定 domain 的資料規則
|
||||
|
||||
#### 5. `components/maint`
|
||||
|
||||
這個目錄目前是最接近 feature folder 的區域,放 maintenance 領域的 page component 與 domain component:
|
||||
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
- [CommonConfirmDialog.vue](../src/components/maint/CommonConfirmDialog.vue)
|
||||
- [EditableGrid.vue](../src/components/maint/EditableGrid.vue)
|
||||
- [MasterFileFormFields.vue](../src/components/maint/MasterFileFormFields.vue)
|
||||
@@ -180,46 +160,48 @@ layout 不應承擔:
|
||||
- [MntRecordNavToolbar.vue](../src/components/maint/MntRecordNavToolbar.vue)
|
||||
- `master-detail/*`
|
||||
|
||||
`master-detail/*` 目前屬於維護頁專用的較細組件群:
|
||||
若只是維護頁專用子元件,不要搬到 `base`。
|
||||
|
||||
- [CourseMobilePanel.vue](../src/components/maint/master-detail/CourseMobilePanel.vue)
|
||||
- [DetailCollapseGropus.vue](../src/components/maint/master-detail/DetailCollapseGropus.vue)
|
||||
- [DetailFullHeightPanel.vue](../src/components/maint/master-detail/DetailFullHeightPanel.vue)
|
||||
- [DetailNavigation.vue](../src/components/maint/master-detail/DetailNavigation.vue)
|
||||
- [DetailSidePanel.vue](../src/components/maint/master-detail/DetailSidePanel.vue)
|
||||
- [DetailSimpleList.vue](../src/components/maint/master-detail/DetailSimpleList.vue)
|
||||
#### 7. `components/layouts`
|
||||
|
||||
結論:
|
||||
layout 實作集中於:
|
||||
|
||||
- `components/maint` 主要扮演 maintenance domain component 層
|
||||
- `CommonConfirmDialog` 可以直接在 maintenance 頁或元件使用,不需要再包一層 CRUD dialog aggregator
|
||||
- 若只是維護頁專用子元件,不要搬到 `base`
|
||||
- [MainLayout.vue](../src/components/layouts/MainLayout.vue)
|
||||
- [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)
|
||||
- `src/components/layouts/main-layout/*`
|
||||
|
||||
layout 只承擔 app shell、drawer、app bar、favorites、breadcrumb 等框架 UI,不承擔頁面專屬業務流程。
|
||||
|
||||
#### 8. `components/base`
|
||||
|
||||
`components/base` 放真正跨頁共用且不屬於特定 domain 的基礎元件:
|
||||
|
||||
- [DraggableDialog.vue](../src/components/base/DraggableDialog.vue)
|
||||
- [BaseFormTextField.vue](../src/components/base/BaseFormTextField.vue)
|
||||
- [BaseFormSelect.vue](../src/components/base/BaseFormSelect.vue)
|
||||
|
||||
只服務單一頁面家族或單一 domain 的元件不要放進 `base`。
|
||||
|
||||
### `src/composables`
|
||||
|
||||
目前已明確分成兩組:
|
||||
目前 composables 分成:
|
||||
|
||||
- `composables/layout/*`
|
||||
- `composables/maint/*`
|
||||
- `page-drivers/*`:頁面資料協調與 page model 組裝。
|
||||
- `commands/*`:命令式副作用流程,例如 create/edit/save/delete。
|
||||
- `layout/*`:AppShell / layout 狀態與事件協調。
|
||||
- `maint/*`:maintenance demo 的表單、CRUD、editable grid 狀態。
|
||||
- 頂層 login / utility composable:`useLoginCaptcha.ts`、`useLoginAnnouncements.ts`、`useApiCall.ts`。
|
||||
|
||||
代表性檔案:
|
||||
責任:
|
||||
|
||||
- [useAdminLayoutState.ts](../src/composables/layout/useAdminLayoutState.ts)
|
||||
- [useThemeToggle.ts](../src/composables/layout/useThemeToggle.ts)
|
||||
- [useMaintenanceCrudFlow.ts](../src/composables/maint/useMaintenanceCrudFlow.ts)
|
||||
- [useStudentMaintenanceForm.ts](../src/composables/maint/useStudentMaintenanceForm.ts)
|
||||
- [useEditableStudentGrid.ts](../src/composables/maint/useEditableStudentGrid.ts)
|
||||
- [useApiCall.ts](../src/composables/useApiCall.ts)
|
||||
|
||||
`composables` 的責任:
|
||||
|
||||
- 放可重用流程
|
||||
- 放可測試的 UI state
|
||||
- 放與模板結構耦合較低的狀態機
|
||||
- 放可重用流程。
|
||||
- 放可測試的 UI state。
|
||||
- 放與模板結構耦合較低的狀態機。
|
||||
- 不 import component 或 view。
|
||||
|
||||
### `src/stores`
|
||||
|
||||
目前 store 已經是正式分層的一部分,而不只是暫時狀態容器。
|
||||
目前 store 是跨頁共享狀態、快取與全域顯示狀態的正式分層。
|
||||
|
||||
代表性檔案:
|
||||
|
||||
@@ -230,25 +212,20 @@ layout 不應承擔:
|
||||
- [favorites.ts](../src/stores/favorites.ts)
|
||||
- [messages.ts](../src/stores/messages.ts)
|
||||
- [snackbar.ts](../src/stores/snackbar.ts)
|
||||
- [loginAnnouncements.ts](../src/stores/loginAnnouncements.ts)
|
||||
- [students.ts](../src/stores/students.ts)
|
||||
- [semesters.ts](../src/stores/semesters.ts)
|
||||
|
||||
責任:
|
||||
|
||||
- 承接跨頁共享狀態
|
||||
- 承接畫面快取與顯示狀態
|
||||
- 作為 view 與 services 之間的狀態收斂點
|
||||
- `app.ts` 目前是空的 Pinia scaffold,尚未承擔實際 app state
|
||||
- 承接跨頁共享狀態。
|
||||
- 承接畫面快取與全域顯示狀態。
|
||||
- 作為 view/page driver/composable 與 services 之間的狀態收斂點。
|
||||
|
||||
規則:
|
||||
|
||||
- store 檔案直接放在 `src/stores/*.ts`
|
||||
- 不要建立 `src/stores/stores/*` 這類重複巢狀目錄
|
||||
`app.ts` 目前是空的 Pinia scaffold,尚未承擔實際 app state。
|
||||
|
||||
### `src/services`
|
||||
|
||||
`services` 現在已經是一層明確的資料存取邊界,不應再被視為附屬工具資料夾。
|
||||
`services` 是 HTTP 與外部 API 邊界。
|
||||
|
||||
代表性檔案:
|
||||
|
||||
@@ -263,101 +240,93 @@ layout 不應承擔:
|
||||
|
||||
責任:
|
||||
|
||||
- 提供 HTTP client
|
||||
- 封裝 API 模組
|
||||
- 統一 token、session 與錯誤處理
|
||||
- 提供 `httpClient`。
|
||||
- 封裝 API 模組。
|
||||
- 統一 token、session 與錯誤處理。
|
||||
|
||||
規則:
|
||||
|
||||
- 元件不直接處理底層 HTTP 細節
|
||||
- 可共享的請求流程優先收斂到 store 或 composable,再由它們呼叫 service
|
||||
- 元件不直接處理底層 HTTP 細節。
|
||||
- service module 不持有 UI 狀態。
|
||||
- 可共享的請求流程優先收斂到 store、page driver 或 composable,再由它們呼叫 service。
|
||||
|
||||
## 目前已落地的分層模式
|
||||
|
||||
### 模式 1:`view -> page component -> page family components`
|
||||
### 模式 1:`view -> page driver -> page component`
|
||||
|
||||
已落地頁面:
|
||||
|
||||
- `Login`
|
||||
- `Home`
|
||||
|
||||
目前的穩定模式是:
|
||||
|
||||
- `view` 負責資料準備與事件協調
|
||||
- page component 負責頁面主畫面組裝
|
||||
- 較細的視覺區塊再拆到對應頁面家族資料夾,例如 `components/login/*`
|
||||
|
||||
### 模式 2:`view -> page component / domain components + maint composables`
|
||||
|
||||
已落地區域:
|
||||
|
||||
- `Settings`
|
||||
- `FncPage`
|
||||
- `views/maint/*`
|
||||
- `components/maint/*`
|
||||
- `composables/maint/*`
|
||||
|
||||
這一層目前是 maintenance 領域最清楚的結構:
|
||||
穩定模式:
|
||||
|
||||
- `views/maint/*` 承接 route 與頁面流程協調
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue) 承接維護頁共用頁面骨架
|
||||
- `components/maint/*` 承接維護頁專用元件
|
||||
- `composables/maint/*` 承接 CRUD 流程、表單狀態與 editable grid 狀態
|
||||
- view 負責掛載 page driver 與 page component。
|
||||
- page driver 負責 page model、事件與頁面狀態協調。
|
||||
- page component 負責頁面主畫面組裝。
|
||||
|
||||
[EditableGrid.vue](../src/views/maint/EditableGrid.vue) 是目前最接近薄 view 的 maintenance 頁面。
|
||||
### 模式 2:`Login.vue -> PageLogin -> login components/composables`
|
||||
|
||||
### 模式 3:`router meta -> App.vue -> layout`
|
||||
登入頁是 template core,功能開關集中在 `Login.vue`:
|
||||
|
||||
- `withCaptcha`
|
||||
- `withAnnouncement`
|
||||
- `withForgotPassword`
|
||||
- `withRememberAccount`
|
||||
|
||||
資料流與 side effect 分別由 `useLoginCaptcha()`、`useLoginAnnouncements()`、`PageLogin` 與 `LoginForm` 承接。
|
||||
|
||||
### 模式 3:`router meta -> AppShell -> layout`
|
||||
|
||||
這一層已正式成立:
|
||||
|
||||
- route 決定 layout 類型
|
||||
- `App.vue` 決定套用哪個 shell
|
||||
- layout 專注在骨架與共用框架 UI
|
||||
|
||||
這代表 layout 的責任邊界不應再回頭混入頁面內部流程。
|
||||
- route 決定 layout 類型。
|
||||
- `AppShell` 決定套用哪個 shell layout。
|
||||
- layout 專注在骨架與共用框架 UI。
|
||||
|
||||
## 命名規則
|
||||
|
||||
### 頁面與 page component
|
||||
|
||||
- 直接被 route 載入的檔案放 `views`
|
||||
- 負責完整頁面畫面組裝的元件,檔名用 `Page` 前綴
|
||||
- page component 不放進 `base`
|
||||
|
||||
目前例子:
|
||||
|
||||
- [PageLogin.vue](../src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](../src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
- 直接被 route 載入的檔案放 `views`。
|
||||
- 負責完整頁面畫面組裝的元件,檔名用 `Page` 前綴。
|
||||
- page component 優先放 `components/pages`;既有 template 外殼可保留在 `components` 根目錄。
|
||||
- page component 不放進 `base`。
|
||||
|
||||
### 資料夾命名
|
||||
|
||||
- 多字資料夾一律使用 `kebab-case`
|
||||
- 不新增 `snake_case` 或 `PascalCase` 資料夾
|
||||
- 多字資料夾一律使用 `kebab-case`。
|
||||
- 不新增 `snake_case` 或 `PascalCase` 資料夾。
|
||||
|
||||
目前例子:
|
||||
|
||||
- `main-layout`
|
||||
- `master-detail`
|
||||
- `page-drivers`
|
||||
|
||||
### domain component 命名
|
||||
### component 命名
|
||||
|
||||
- 與特定領域強綁定的元件,優先用領域意圖命名
|
||||
- 不要為了抽象而保留含糊的舊前綴
|
||||
- 若元件只在 maint 領域使用,就留在 `components/maint`
|
||||
- Page component:`PageXxx.vue`
|
||||
- Section component:`SectionXxx.vue`
|
||||
- Item component:`ItemXxx.vue`
|
||||
- Base component:不使用 `Page` / `Section` / `Item` 前綴,直接以功能命名。
|
||||
|
||||
## 新增或修改檔案時的判斷準則
|
||||
|
||||
1. 這個檔案是否直接被 route 載入?
|
||||
- 是:優先放 `views`
|
||||
- 是:優先放 `views`。
|
||||
2. 這個檔案是否負責某個完整頁面的主畫面組裝?
|
||||
- 是:用 `Page` 前綴,放 page component 層,不要塞進 `base`
|
||||
- 是:用 `Page` 前綴,優先放 `components/pages`,不要塞進 `base`。
|
||||
3. 這段重複的是模板還是流程?
|
||||
- 模板:抽元件
|
||||
- 流程:抽 composable 或 store
|
||||
- 模板:抽元件。
|
||||
- 流程:抽 composable、page driver、command 或 store。
|
||||
4. 這個狀態是否跨頁共享,或需要快取 / 全域顯示控制?
|
||||
- 是:優先考慮 store
|
||||
- 是:優先考慮 store。
|
||||
5. 這個邏輯是否在處理 API、token、session、錯誤正規化?
|
||||
- 是:放 `services`
|
||||
6. 這個元件是否只屬於單一 domain?
|
||||
- 是:優先放到該 domain 目錄,例如 `components/maint`
|
||||
- 是:放 `services`。
|
||||
6. 這個元件是否只屬於單一 domain 或單一頁面家族?
|
||||
- 是:優先放到該 domain / feature 目錄,例如 `components/maint` 或 `components/login`。
|
||||
7. 這個抽象是否真的降低重複與理解成本?
|
||||
- 否:不要抽
|
||||
- 否:不要抽。
|
||||
|
||||
Reference in New Issue
Block a user