# 事件与回调

<cite>
**本文引用的文件列表**
- [ProTable.vue](file://packages/components/ProTable.vue)
- [ProSearch.vue](file://packages/components/ProSearch.vue)
- [ProForm.vue](file://packages/components/ProForm.vue)
- [ProTableEdit.vue](file://packages/components/ProTableEdit.vue)
- [request.js](file://packages/libs/request.js)
- [ProTable.d.ts](file://types/ProTable.d.ts)
- [ProTable.vue（示例）](file://src/views/ProTable.vue)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构与定位](#项目结构与定位)
3. [核心组件与职责](#核心组件与职责)
4. [架构总览](#架构总览)
5. [事件与回调详解](#事件与回调详解)
6. [依赖关系分析](#依赖关系分析)
7. [性能与最佳实践](#性能与最佳实践)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)

## 简介
本章节系统梳理 ProTable 的事件与回调机制，覆盖搜索、分页、操作按钮、数据加载、表单提交等关键事件的触发时机、参数结构与处理方式，并提供调试与性能优化建议。目标是帮助开发者快速掌握事件驱动的数据流与交互模式。

## 项目结构与定位
- ProTable 作为主表格组件，负责：
  - 组织搜索、分页、工具栏、表单弹窗等子组件
  - 发起数据请求、解析响应、更新内部状态
  - 向父组件派发事件，供外部监听与联动
- 子组件：
  - ProSearch：封装搜索表单与“搜索/重置”事件
  - ProForm：封装表单渲染与校验、提交流程
  - ProTableEdit：编辑态表格，包含分页、保存、删除等交互
- 请求库 request.js：统一处理 GET/POST、URL 占位替换、headers 注入等

```mermaid
graph TB
PT["ProTable.vue"] --> PS["ProSearch.vue"]
PT --> PF["ProForm.vue"]
PT --> REQ["request.js"]
PTE["ProTableEdit.vue"] --> REQ
PT --> |"emit: search/searchReset/formReset/fetchFinish"| Parent["父组件/调用方"]
```

图表来源
- [ProTable.vue:423-428](file://packages/components/ProTable.vue#L423-L428)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [ProTableEdit.vue:1-1148](file://packages/components/ProTableEdit.vue#L1-L1148)

章节来源
- [ProTable.vue:423-428](file://packages/components/ProTable.vue#L423-L428)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [ProTableEdit.vue:1-1148](file://packages/components/ProTableEdit.vue#L1-L1148)

## 核心组件与职责
- ProTable
  - 负责数据请求、分页、搜索、表单弹窗、操作按钮动作、全屏状态监听等
  - 提供事件：search、searchReset、formReset、fetchFinish、pageClick、uiConfig 等
- ProSearch
  - 负责搜索表单项渲染与交互，对外发出“search”事件
  - 支持 beforeSearch 钩子，允许在搜索前执行前置逻辑
- ProForm
  - 负责表单渲染、校验、提交；支持 submitForm 配置与成功条件判断
- request.js
  - 统一请求入口，支持字符串 URL、对象配置、函数式请求
  - 自动注入 Authorization 头（从查询参数读取）
- ProTableEdit
  - 编辑态表格，内置分页、保存、删除、恢复等交互，触发 search、searchReset、pageChange、pageSizeChange 等事件

章节来源
- [ProTable.vue:456-850](file://packages/components/ProTable.vue#L456-L850)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [ProTableEdit.vue:879-1148](file://packages/components/ProTableEdit.vue#L879-L1148)

## 架构总览
下图展示 ProTable 与子组件、请求库之间的交互关系及事件流向。

```mermaid
sequenceDiagram
participant U as "用户"
participant PT as "ProTable"
participant PS as "ProSearch"
participant PF as "ProForm"
participant R as "request.js"
U->>PS : 触发搜索
PS-->>PT : emit("search")
PT->>PT : searchAction()/search()
PT->>R : customRequest({ request, method, headers, datas })
R-->>PT : 返回响应
PT->>PT : 解析数据/设置 total
PT-->>U : emit("fetchFinish", data)
PT-->>U : emit("search"/"searchReset"/"formReset")
U->>PF : 打开表单并提交
PF-->>PT : submit() 校验通过
PT->>R : customRequest({ request, method, headers, datas })
R-->>PT : 返回响应
PT->>PT : successHandle()/success()/error()
```

图表来源
- [ProTable.vue:605-648](file://packages/components/ProTable.vue#L605-L648)
- [ProTable.vue:665-737](file://packages/components/ProTable.vue#L665-L737)
- [ProTable.vue:782-830](file://packages/components/ProTable.vue#L782-L830)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)

## 事件与回调详解

### 1) 搜索事件
- 触发时机
  - 用户点击搜索按钮或按回车
  - ProSearch 内部调用 search 方法时
- 事件名称
  - search：搜索开始
  - searchReset：重置搜索表单后触发
- 参数结构
  - search/searchReset：包含 form、page、talbe 三部分
    - form：当前搜索表单值
    - page：当前页码与每页大小
    - talbe：当前表格数据
- 处理方式
  - ProTable 在搜索后会重新发起数据请求，并在请求完成后通过 emitActions 派发事件
  - 可通过 beforeSearch 钩子在搜索前执行异步逻辑（如确认未保存修改）

章节来源
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProTable.vue:625-648](file://packages/components/ProTable.vue#L625-L648)
- [ProTable.vue:655-661](file://packages/components/ProTable.vue#L655-L661)

### 2) 分页事件
- 触发时机
  - 用户切换页码或调整每页数量
- 事件名称
  - pageClick：分页点击事件（携带原生事件对象）
  - uiConfig：UI 配置变更事件（携带配置对象）
- 参数结构
  - pageClick：原生事件对象 e
  - uiConfig：options（配置对象）
- 处理方式
  - ProTable 内部维护 page.current/pageSize，调用 search 或 fetchCurrent 更新数据
  - 可通过 watch pageSize 将外部 pageSize 同步到内部

章节来源
- [ProTable.vue:457-461](file://packages/components/ProTable.vue#L457-L461)
- [ProTable.vue:840-842](file://packages/components/ProTable.vue#L840-L842)

### 3) 表单提交事件
- 触发时机
  - 打开表单对话框后点击提交
- 事件名称
  - submit：表单提交（由 ProForm 触发，ProTable 内部处理）
- 参数结构
  - submit：包含表单数据、请求地址、方法等
- 处理方式
  - ProTable 内部先进行表单校验，再调用 customRequest 发送请求
  - 成功后根据 success 条件判断是否提示成功并刷新数据

章节来源
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [ProTable.vue:799-830](file://packages/components/ProTable.vue#L799-L830)

### 4) 数据加载完成事件
- 触发时机
  - 每次数据请求完成后
- 事件名称
  - fetchFinish：数据加载完成
- 参数结构
  - fetchFinish：data（后端返回的列表数据片段）
- 处理方式
  - ProTable 在解析完数据后立即触发该事件，便于外部做二次处理（如统计、埋点）

章节来源
- [ProTable.vue:721-721](file://packages/components/ProTable.vue#L721-L721)

### 5) 表单重置事件
- 触发时机
  - 用户点击重置按钮或调用 resetForm
- 事件名称
  - formReset：表单重置完成
- 参数结构
  - formReset：同 search/searchReset，包含 form、page、talbe
- 处理方式
  - ProTable 重置表单并重新请求数据，随后派发事件

章节来源
- [ProTable.vue:649-654](file://packages/components/ProTable.vue#L649-L654)

### 6) 行点击事件
- 触发时机
  - 用户点击表格某一行
- 事件名称
  - table:on-row-click：行点击事件
- 参数结构
  - 由底层表格组件传入，通常包含 row、index、column 等
- 处理方式
  - ProTable 通过 v-on 接收并转发到父组件

章节来源
- [ProTable.vue（示例）:15-16](file://src/views/ProTable.vue#L15-L16)

### 7) 操作按钮事件
- 触发时机
  - 用户点击列中定义的操作按钮（如删除、查看、自定义 action）
- 事件名称
  - typeAction：内部处理动作（如 delete、action）
- 参数结构
  - typeAction：val（按钮配置）、params（行数据、索引等）
- 处理方式
  - ProTable 内部根据按钮类型决定打开表单弹窗或直接执行删除确认

章节来源
- [ProTable.vue:555-604](file://packages/components/ProTable.vue#L555-L604)

### 8) 编辑态表格事件（ProTableEdit）
- 触发时机
  - 编辑态表格的搜索、重置、分页切换、保存等操作
- 事件名称
  - search、searchReset、pageChange、pageSizeChange、save（保存成功）
- 参数结构
  - search/searchReset：编辑态初始值与当前值对比
  - pageChange/pageSizeChange：当前页与每页大小
  - save：保存结果与分页状态
- 处理方式
  - ProTableEdit 内部维护 editList、initialValue 等状态，保存成功后可自动刷新或跳转页码

章节来源
- [ProTableEdit.vue:896-920](file://packages/components/ProTableEdit.vue#L896-L920)
- [ProTableEdit.vue:718-754](file://packages/components/ProTableEdit.vue#L718-L754)

## 依赖关系分析

```mermaid
classDiagram
class ProTable {
+props : columns, request, submitForm, map, search, form, table
+methods : search(), fetch(), submit(), emitActions()
+events : "search","searchReset","formReset","fetchFinish","pageClick","uiConfig"
}
class ProSearch {
+methods : search(), reset()
+events : "search","reset"
}
class ProForm {
+methods : validate(), submit(), reset()
+events : "submit"
}
class Request {
+customRequest()
}
ProTable --> ProSearch : "组合"
ProTable --> ProForm : "组合"
ProTable --> Request : "调用"
ProSearch --> ProTable : "emit(search/reset)"
ProForm --> ProTable : "submit"
```

图表来源
- [ProTable.vue:423-428](file://packages/components/ProTable.vue#L423-L428)
- [ProTable.vue:605-661](file://packages/components/ProTable.vue#L605-L661)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)

章节来源
- [ProTable.vue:423-428](file://packages/components/ProTable.vue#L423-L428)
- [ProSearch.vue:180-189](file://packages/components/ProSearch.vue#L180-L189)
- [ProForm.vue:1-200](file://packages/components/ProForm.vue#L1-L200)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)

## 性能与最佳实践
- 请求节流与防抖
  - 在高频搜索场景，建议在外层对 search 事件进行节流/防抖，避免频繁请求
- 分页策略
  - 使用 pageSizeChange 时，仅在第一页触发请求，减少不必要的网络开销
- 响应解析
  - 合理配置 map.dataPath、map.totalPath，确保数据解析正确，避免重复渲染
- 成功条件判断
  - 通过 map.success 或 form.success 配置成功条件，避免误判导致的 UI 闪烁
- 异步处理
  - beforeSearch/beforeReset 支持异步逻辑，注意在异步完成后再调用回调以继续搜索/重置
- 加载状态
  - 利用 loading/fetchFinish 控制加载指示与后续处理，提升用户体验

[本节为通用建议，不直接分析具体文件]

## 故障排查指南
- 数据路径不匹配
  - 现象：表格为空、total 为 0
  - 排查：检查 map.dataPath、map.totalPath 是否与后端返回一致
- 请求失败
  - 现象：控制台报错、提示“请求出错”
  - 排查：确认 request 配置、headers、Authorization 是否正确
- 成功条件不满足
  - 现象：提交成功但未提示成功
  - 排查：检查 map.success/form.success 配置是否与后端返回一致
- 事件未触发
  - 现象：父组件未收到 search/searchReset 等事件
  - 排查：确认是否正确绑定事件监听；检查 emitActions 的调用时机

章节来源
- [ProTable.vue:705-731](file://packages/components/ProTable.vue#L705-L731)
- [ProTable.vue:782-798](file://packages/components/ProTable.vue#L782-L798)
- [request.js:39-77](file://packages/libs/request.js#L39-L77)

## 结论
ProTable 的事件体系围绕“搜索—分页—数据加载—表单提交—操作按钮”形成闭环，通过 emitActions 与 fetchFinish 等事件实现与父组件的解耦联动。合理利用事件参数与生命周期钩子，可构建高性能、可维护的表格交互体验。建议在实际项目中结合业务场景对事件进行封装与统一管理，以提升可测试性与可扩展性。