first commit
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
---
|
||||
description: 后台页面(列表/表单/详情)开发范式 —— 新增或修改 views 下页面时必读
|
||||
globs: ["src/views/**/*.vue", "src/views/**/*.ts", "src/components/**/*.vue"]
|
||||
---
|
||||
|
||||
# 页面开发范式
|
||||
|
||||
## 标准列表页结构
|
||||
一个规范的列表页自上而下固定为四段:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 1. 搜索栏:el-form inline + 查询/重置 -->
|
||||
<!-- 2. 工具栏:新增 / 批量删除 / 导入导出 -->
|
||||
<!-- 3. 表格:el-table + 操作列 -->
|
||||
<!-- 4. 分页:el-pagination -->
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
- 搜索栏支持回车查询与"重置"重置到初始查询条件。
|
||||
- 表格必须 `v-loading="loading"`、`border`、操作列 `fixed="right"`。
|
||||
- 分页器 `layout="total, sizes, prev, pager, next, jumper"`,与 `queryParams.pageNum/pageSize` 双向联动。
|
||||
- 查询条件与分页状态变更时用 `watch` 或统一 `handleQuery` 重新拉取,**禁止在模板里调用接口**。
|
||||
|
||||
## 标准数据流
|
||||
```ts
|
||||
const loading = ref(false)
|
||||
const total = ref(0)
|
||||
const list = ref<UserVO[]>([])
|
||||
const queryParams = reactive<UserQuery>({ pageNum: 1, pageSize: 10 })
|
||||
|
||||
async function handleQuery() {
|
||||
loading.value = true
|
||||
try {
|
||||
const { list: rows, total: t } = await UserAPI.query(queryParams)
|
||||
list.value = rows
|
||||
total.value = t
|
||||
} finally {
|
||||
loading.value = false // loading 必须在 finally 里关闭
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(handleQuery)
|
||||
```
|
||||
|
||||
- 请求失败由 `request` 拦截器统一提示,页面**只负责数据与 loading**;确需额外处理时才 `catch`。
|
||||
- `loading` 必须放在 `finally` 关闭,避免异常时永久转圈。
|
||||
|
||||
## 表单弹窗
|
||||
1. 弹窗组件独立文件,父组件通过 `ref` + `defineExpose({ open })` 调用:
|
||||
```vue
|
||||
<UserForm ref="formRef" @submit="handleQuery" />
|
||||
```
|
||||
2. 弹窗内部:`el-dialog` + `el-form`,必须有 `ref`、`rules`、`:model`;关闭时 `resetFields()` 并清空隐藏主键。
|
||||
3. 提交按钮在请求期间设置 `confirmLoading`,防止重复提交。
|
||||
4. 新增与编辑复用同一弹窗,通过是否有 `id` 区分,标题用 computed 切换。
|
||||
|
||||
## 删除与危险操作
|
||||
- 删除必须走 `ElMessageBox.confirm` 二次确认,成功后 `ElMessage.success` + 刷新列表。
|
||||
- 若当前页删完且非第一页,需回退 `pageNum` 再查询。
|
||||
|
||||
## 表单校验
|
||||
- 规则写在 `rules` 常量里(`const rules = reactive<FormRules<UserForm>>({...})`),不在模板内联。
|
||||
- 提交前必须 `await formRef.value.validate()`,校验失败直接返回。
|
||||
- 后端返回字段级错误需映射到 `formRef` 对应字段。
|
||||
|
||||
## 页面内复用
|
||||
- 仅当前页面使用的子组件放 `views/{module}/components/`,**不要**放进全局 `src/components/`。
|
||||
- 跨页面复用的逻辑抽成 `useXxx` 组合式函数,放 `src/composables/`。
|
||||
- 字典/枚举下拉数据统一走 Pinia 的字典 store 缓存,不得每次打开弹窗都重新请求。
|
||||
Reference in New Issue
Block a user