55 lines
2.4 KiB
Markdown
55 lines
2.4 KiB
Markdown
# Vue Page — 页面模板与 Store
|
||
|
||
> 主流程见 SKILL.md,本文档为列表页/详情页/路由/Pinia/Provider 的完整实现。
|
||
>
|
||
> **⚠️ 双前端区分**:本文件中使用 `el-*` 组件的模板**仅适用于管理端** (`Case-Database-Frontend-admin/`)。
|
||
> 用户端 (`Case-Database-Frontend-user/`) 使用 Headless UI + Tailwind CSS,**禁止引入 Element Plus**。
|
||
|
||
## 列表页模板
|
||
|
||
```vue
|
||
<script setup>
|
||
import { useTable } from '@/hooks/useTable'
|
||
document.title = '{{PageTitle}} - {{AppName}}'
|
||
const { loading, dataList, pagination, loadData } = useTable((params) => {{resource}}Api.list(params))
|
||
const searchForm = reactive({ keyword: '', status: '' })
|
||
function handleSearch() { pagination.current = 1; loadData() }
|
||
onMounted(() => loadData())
|
||
</script>
|
||
<template>
|
||
<div class="p-4 space-y-4">
|
||
<el-card><el-form :model="searchForm" inline>...</el-form></el-card>
|
||
<el-card>
|
||
<template #header><span>{{PageTitle}}</span><el-button @click="handleCreate">新增</el-button></template>
|
||
<el-table v-loading="loading" :data="dataList" border stripe>...</el-table>
|
||
<el-pagination v-model:current-page="pagination.current" ... @current-change="loadData" />
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
## 详情页模板
|
||
|
||
使用 useRoute/useRouter,fetchDetail 加载数据,el-skeleton 加载态,el-page-header + el-descriptions。
|
||
|
||
## 路由配置
|
||
|
||
```typescript
|
||
const routes = [
|
||
{ path: '/{{module}}/{{route-path}}', name: '{{RouteName}}', component: () => import('@/views/...'), meta: { title, requiresAuth: true, permission } },
|
||
{ path: '/{{module}}/{{route-path}}/:id', name: '{{RouteName}}Detail', ... }
|
||
]
|
||
```
|
||
|
||
## Pinia Store — List 与 Detail 分离
|
||
|
||
ListItem 类型:轻量,排除大文本/复杂对象/大数组。Detail 类型:完整字段。Store:list (array)、detailMap (Record<id, Detail>)、loadingDetailIds、getDetail(id)、isDetailLoading(id)、fetchList、fetchDetail(有缓存则返回)、invalidateDetail、invalidateAll。
|
||
|
||
## 页面级 Provider 模式
|
||
|
||
当 ≥3 个子组件共享状态时:provider.vue provide 状态+actions,keys.ts 定义 PAGE_KEY + usePageContext,子组件 inject。文件结构:index.vue、provider.vue、keys.ts、components/SearchBar/DataTable/BatchActions、composables/usePageData。
|
||
|
||
## 动态路由 (RBAC)
|
||
|
||
loadDynamicRoutes:menuStore.fetchMenus(),router.addRoute('layout', { path, name, component: () => import(...), meta })。
|