refactor: simplify page models and view driver usage

Move simple page models into page components and build trivial computed
models directly in views to avoid unnecessary page drivers. Update views
to destructure page driver returns and rely on template ref unwrapping,
and document the guidance for when page drivers should be introduced.refactor: simplify page models and view driver usage

Move simple page models into page components and build trivial computed
models directly in views to avoid unnecessary page drivers. Update views
to destructure page driver returns and rely on template ref unwrapping,
and document the guidance for when page drivers should be introduced.
This commit is contained in:
skytek_xinliang
2026-05-27 11:10:34 +08:00
parent 799b16578d
commit b8664b5c3e
19 changed files with 139 additions and 220 deletions
+12 -3
View File
@@ -1,10 +1,19 @@
<script setup lang="ts">
import { computed } from 'vue'
import PageEditableGridMaintenance from '@/components/pages/PageEditableGridMaintenance.vue'
import { useEditableGridMaintenancePage } from '@/composables/page-drivers/useEditableGridMaintenancePage'
import type { MaintenancePageModel } from '@/models/page'
import { useStudentStore } from '@/stores/students'
const page = useEditableGridMaintenancePage()
const studentStore = useStudentStore()
const pageModel = computed<MaintenancePageModel>(() => ({
type: 'maintenance',
title: '可編輯表格維護示範',
records: studentStore.students,
loading: false,
error: null,
}))
</script>
<template>
<PageEditableGridMaintenance :page="page.pageModel.value" />
<PageEditableGridMaintenance :page="pageModel" />
</template>
+25 -21
View File
@@ -2,33 +2,37 @@
import PageMasterDetailAMaintenance from '@/components/pages/PageMasterDetailAMaintenance.vue'
import { useMasterDetailAMaintenancePage } from '@/composables/page-drivers/useMasterDetailAMaintenancePage'
const page = useMasterDetailAMaintenancePage()
const {
currentPage, formState, itemsPerPage, masterDetailEvents, masterDetailProps,
openAddDialog, openEditDialog, openViewDialog, pageCount, pageModel, pageSummary,
resetSearch, search, searchPanelOpen, snackbarVisible, students, tableHeaders,
} = useMasterDetailAMaintenancePage()
</script>
<template>
<PageMasterDetailAMaintenance
v-model:search="page.search.value"
v-model:search-panel-open="page.searchPanelOpen.value"
v-bind="page.masterDetailProps.value"
:current-page="page.currentPage.value"
:grade-label="page.formState.gradeLabel"
:headers="page.tableHeaders.value"
:items="page.students.value"
:items-per-page="page.itemsPerPage"
:page="page.pageModel.value"
:page-count="page.pageCount.value"
:page-summary="page.pageSummary.value"
:row-props="page.formState.rowProps"
:status-color="page.formState.statusColor"
@create="page.openAddDialog"
@edit="page.openEditDialog"
@reset-search="page.resetSearch"
@update:current-page="page.currentPage.value = $event"
@view="page.openViewDialog"
v-on="page.masterDetailEvents"
v-model:search="search"
v-model:search-panel-open="searchPanelOpen"
v-bind="masterDetailProps"
:current-page="currentPage"
:grade-label="formState.gradeLabel"
:headers="tableHeaders"
:items="students"
:items-per-page="itemsPerPage"
:page="pageModel"
:page-count="pageCount"
:page-summary="pageSummary"
:row-props="formState.rowProps"
:status-color="formState.statusColor"
@create="openAddDialog"
@edit="openEditDialog"
@reset-search="resetSearch"
@update:current-page="currentPage = $event"
@view="openViewDialog"
v-on="masterDetailEvents"
/>
<v-snackbar v-model="page.snackbarVisible.value" color="success" location="bottom right" :timeout="2200">
<v-snackbar v-model="snackbarVisible" color="success" location="bottom right" :timeout="2200">
儲存成功
</v-snackbar>
</template>
+12 -3
View File
@@ -1,10 +1,19 @@
<script setup lang="ts">
import { computed } from 'vue'
import PageMasterDetailBMaintenance from '@/components/pages/PageMasterDetailBMaintenance.vue'
import { useMasterDetailBMaintenancePage } from '@/composables/page-drivers/useMasterDetailBMaintenancePage'
import type { MaintenancePageModel } from '@/models/page'
import { useStudentStore } from '@/stores/students'
const page = useMasterDetailBMaintenancePage()
const studentStore = useStudentStore()
const pageModel = computed<MaintenancePageModel>(() => ({
type: 'maintenance',
title: '主從資料維護示範B',
records: studentStore.students,
loading: false,
error: null,
}))
</script>
<template>
<PageMasterDetailBMaintenance :page="page.pageModel.value" />
<PageMasterDetailBMaintenance :page="pageModel" />
</template>
+12 -3
View File
@@ -1,10 +1,19 @@
<script setup lang="ts">
import { computed } from 'vue'
import PageMasterDetailCMaintenance from '@/components/pages/PageMasterDetailCMaintenance.vue'
import { useMasterDetailCMaintenancePage } from '@/composables/page-drivers/useMasterDetailCMaintenancePage'
import type { MaintenancePageModel } from '@/models/page'
import { useStudentStore } from '@/stores/students'
const page = useMasterDetailCMaintenancePage()
const studentStore = useStudentStore()
const pageModel = computed<MaintenancePageModel>(() => ({
type: 'maintenance',
title: '主從資料維護示範C',
records: studentStore.students,
loading: false,
error: null,
}))
</script>
<template>
<PageMasterDetailCMaintenance :page="page.pageModel.value" />
<PageMasterDetailCMaintenance :page="pageModel" />
</template>
+29 -24
View File
@@ -5,48 +5,53 @@ import SectionFormPanel from '@/components/sections/SectionFormPanel.vue'
import SectionSearchPanel from '@/components/sections/SectionSearchPanel.vue'
import { useSingleRecordMaintenancePage } from '@/composables/page-drivers/useSingleRecordMaintenancePage'
const page = useSingleRecordMaintenancePage()
const {
commands, currentPage, departments, flow, formPanelEvents, formPanelProps,
formState, gradeOptions, itemsPerPage, pageCount, pageModel, pageSummary,
resetSearch, search, searchPanelOpen, snackbarVisible,
statuses, students, tableHeaders,
} = useSingleRecordMaintenancePage()
</script>
<template>
<PageMaintenance
v-model:search-panel-open="page.searchPanelOpen.value"
:page="page.pageModel.value"
@create="page.commands.openAddDialog"
v-model:search-panel-open="searchPanelOpen"
:page="pageModel"
@create="commands.openAddDialog"
>
<template #search-fields>
<SectionSearchPanel
v-model="page.search.value"
:departments="page.departments"
:grade-options="page.gradeOptions"
:statuses="page.statuses"
@reset="page.resetSearch"
v-model="search"
:departments="departments"
:grade-options="gradeOptions"
:statuses="statuses"
@reset="resetSearch"
/>
</template>
<template #table>
<SectionDataTable
v-model:current-page="page.currentPage.value"
:grade-label="page.formState.gradeLabel"
:headers="page.tableHeaders.value"
:items="page.students.value"
:items-per-page="page.itemsPerPage"
:page-count="page.pageCount.value"
:page-summary="page.pageSummary.value"
:row-props="page.formState.rowProps"
:status-color="page.formState.statusColor"
@delete="page.flow.requestDeleteConfirmation"
@edit="page.commands.openEditDialog"
@view="page.commands.openViewDialog"
v-model:current-page="currentPage"
:grade-label="formState.gradeLabel"
:headers="tableHeaders"
:items="students"
:items-per-page="itemsPerPage"
:page-count="pageCount"
:page-summary="pageSummary"
:row-props="formState.rowProps"
:status-color="formState.statusColor"
@delete="flow.requestDeleteConfirmation"
@edit="commands.openEditDialog"
@view="commands.openViewDialog"
/>
</template>
</PageMaintenance>
<SectionFormPanel
v-bind="page.formPanelProps.value"
v-on="page.formPanelEvents"
v-bind="formPanelProps"
v-on="formPanelEvents"
/>
<v-snackbar v-model="page.snackbarVisible.value" color="success" location="bottom right" :timeout="2200">
<v-snackbar v-model="snackbarVisible" color="success" location="bottom right" :timeout="2200">
儲存成功
</v-snackbar>
</template>