# 搜索与筛选

<cite>
**本文引用的文件**
- [ProSearch.vue](file://packages/components/ProSearch.vue)
- [ProTable.vue](file://packages/components/ProTable.vue)
- [ProTable.d.ts](file://types/ProTable.d.ts)
- [ProTable 示例页面](file://src/views/ProTable.vue)
- [ProSearch 示例页面](file://src/views/ProSearch.vue)
- [ProForm 示例页面](file://src/views/ProForm.vue)
- [表格渲染示例](file://src/views/TableRender.vue)
- [请求封装 request.js](file://packages/libs/request.js)
- [主入口 main.js](file://src/main.js)
- [项目说明 README.md](file://README.md)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本章节面向使用 ProTable 的开发者，系统性讲解“搜索与筛选”能力：如何通过列级配置定义搜索字段、如何组合搜索条件、如何与 ProTable 集成触发查询、如何重置搜索以及如何管理搜索状态；同时覆盖高级场景（复杂条件组合、搜索历史建议等）与性能优化、用户体验改进建议，并提供可直接参考的配置示例与最佳实践。

## 项目结构
围绕搜索与筛选功能，关键文件与职责如下：
- ProSearch：通用搜索表单组件，负责渲染列级搜索控件、触发搜索/重置事件、支持折叠展开、标签宽度与网格布局等。
- ProTable：表格容器组件，内置搜索区，将 ProSearch 与分页、工具栏、表格主体整合，统一管理搜索状态、分页参数与数据请求。
- 类型定义：ProTable.d.ts 提供搜索相关属性的类型约束，帮助 IDE 与使用者理解配置项。
- 示例页面：演示 ProSearch 与 ProTable 的使用方式、列级搜索配置、日期范围、下拉选择等常见场景。
- 请求封装：request.js 封装了 GET/POST 参数抽取、URL 占位替换、鉴权头注入等，被 ProTable 内部调用以发起远程请求。

```mermaid
graph TB
subgraph "视图层"
VPT["ProTable 示例页面<br/>src/views/ProTable.vue"]
VPS["ProSearch 示例页面<br/>src/views/ProSearch.vue"]
VPF["ProForm 示例页面<br/>src/views/ProForm.vue"]
VR["表格渲染示例<br/>src/views/TableRender.vue"]
end
subgraph "组件层"
CPT["ProTable.vue<br/>packages/components/ProTable.vue"]
CPS["ProSearch.vue<br/>packages/components/ProSearch.vue"]
end
subgraph "基础设施"
REQ["请求封装 request.js<br/>packages/libs/request.js"]
MAIN["主入口 main.js<br/>src/main.js"]
TYP["类型定义 ProTable.d.ts<br/>types/ProTable.d.ts"]
end
VPT --> CPT
VPS --> CPS
VPF --> CPT
VR --> CPT
CPT --> CPS
CPT --> REQ
MAIN --> CPT
TYP --> CPT
```

**图表来源**
- [ProTable 示例页面:1-306](file://src/views/ProTable.vue#L1-L306)
- [ProSearch 示例页面:1-59](file://src/views/ProSearch.vue#L1-L59)
- [ProForm 示例页面:1-198](file://src/views/ProForm.vue#L1-L198)
- [表格渲染示例:1-51](file://src/views/TableRender.vue#L1-L51)
- [ProTable.vue:1-957](file://packages/components/ProTable.vue#L1-L957)
- [ProSearch.vue:1-271](file://packages/components/ProSearch.vue#L1-L271)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [main.js:1-14](file://src/main.js#L1-L14)
- [ProTable.d.ts:1-59](file://types/ProTable.d.ts#L1-L59)

**章节来源**
- [ProTable 示例页面:1-306](file://src/views/ProTable.vue#L1-L306)
- [ProSearch 示例页面:1-59](file://src/views/ProSearch.vue#L1-L59)
- [ProForm 示例页面:1-198](file://src/views/ProForm.vue#L1-L198)
- [表格渲染示例:1-51](file://src/views/TableRender.vue#L1-L51)
- [ProTable.vue:1-957](file://packages/components/ProTable.vue#L1-L957)
- [ProSearch.vue:1-271](file://packages/components/ProSearch.vue#L1-L271)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [main.js:1-14](file://src/main.js#L1-L14)
- [ProTable.d.ts:1-59](file://types/ProTable.d.ts#L1-L59)

## 核心组件
- ProSearch：负责渲染搜索表单项、收集用户输入、发出搜索/重置事件；支持标签位置（左/上）、网格列数、标签宽度、折叠展开、回车触发搜索等。
- ProTable：负责管理搜索状态、分页状态、请求参数拼装、远程数据获取与渲染；内部嵌入 ProSearch 并将其与分页联动；提供 search/reset 方法与事件回调。
- 类型约束：ProTable.d.ts 明确 search、form、table、page 等配置项的结构，便于静态校验与 IDE 提示。

**章节来源**
- [ProSearch.vue:114-218](file://packages/components/ProSearch.vue#L114-L218)
- [ProTable.vue:154-851](file://packages/components/ProTable.vue#L154-L851)
- [ProTable.d.ts:1-59](file://types/ProTable.d.ts#L1-L59)

## 架构总览
ProTable 在其模板中内嵌 ProSearch，并通过 v-model 双向绑定搜索表单值。当用户点击“搜索”或按回车时，ProSearch 发出 search 事件；ProTable 接收后重置页码到第一页并发起请求；分页组件变更页码或页大小时也会触发请求；重置时恢复初始搜索值并重新请求。

```mermaid
sequenceDiagram
participant U as "用户"
participant PS as "ProSearch"
participant PT as "ProTable"
participant RQ as "请求封装 request.js"
U->>PS : 输入搜索条件/点击搜索
PS-->>PT : 触发 search 事件
PT->>PT : 重置页码为1
PT->>RQ : 携带 {分页参数, 搜索表单值} 发起请求
RQ-->>PT : 返回数据
PT-->>U : 渲染表格与分页
U->>PS : 点击重置
PS-->>PT : 触发 reset 事件
PT->>PT : 恢复初始搜索值
PT->>RQ : 重新发起请求
RQ-->>PT : 返回数据
PT-->>U : 渲染表格与分页
```

**图表来源**
- [ProTable.vue:17-26](file://packages/components/ProTable.vue#L17-L26)
- [ProTable.vue:625-648](file://packages/components/ProTable.vue#L625-L648)
- [ProTable.vue:665-741](file://packages/components/ProTable.vue#L665-L741)
- [ProSearch.vue:181-189](file://packages/components/ProSearch.vue#L181-L189)
- [request.js:39-77](file://packages/libs/request.js#L39-L77)

**章节来源**
- [ProTable.vue:17-26](file://packages/components/ProTable.vue#L17-L26)
- [ProTable.vue:625-648](file://packages/components/ProTable.vue#L625-L648)
- [ProTable.vue:665-741](file://packages/components/ProTable.vue#L665-L741)
- [ProSearch.vue:181-189](file://packages/components/ProSearch.vue#L181-L189)
- [request.js:39-77](file://packages/libs/request.js#L39-L77)

## 详细组件分析

### ProSearch：搜索表单组件
- 渲染逻辑
  - 使用网格布局根据列数与每列跨度自动排布搜索项。
  - 若列定义了 renderSearch，则使用 ProTypeItem 渲染对应控件；否则使用默认 Input。
  - 支持标签位置（left/top）、标签宽度、按钮插槽、折叠展开、回车触发搜索。
- 事件与状态
  - 提供 search 与 reset 事件；支持 beforeSearch/beforeReset 钩子以拦截或二次确认。
  - 通过 v-model 同步搜索值；wapperInput 用于处理需要包装格式的输入（如日期范围）。
- 性能与可用性
  - 大量列时支持折叠/展开，减少首屏高度。
  - loading 状态禁用重置按钮，避免并发问题。

```mermaid
flowchart TD
Start(["进入 ProSearch"]) --> CheckRender["是否存在 renderSearch?"]
CheckRender --> |是| RenderCustom["使用 ProTypeItem 渲染控件"]
CheckRender --> |否| RenderDefault["使用默认 Input 渲染"]
RenderCustom --> BindModel["v-model 绑定 modelValue[key]"]
RenderDefault --> BindModel
BindModel --> EnterKey{"是否按下回车?"}
EnterKey --> |是| EmitSearch["触发 search 事件"]
EnterKey --> |否| Wait["等待用户继续输入"]
EmitSearch --> End(["结束"])
Wait --> End
```

**图表来源**
- [ProSearch.vue:1-112](file://packages/components/ProSearch.vue#L1-L112)
- [ProSearch.vue:155-189](file://packages/components/ProSearch.vue#L155-L189)

**章节来源**
- [ProSearch.vue:1-271](file://packages/components/ProSearch.vue#L1-L271)

### ProTable：表格与搜索的集成
- 搜索区集成
  - 在模板中内嵌 ProSearch，并将 columns 中的 notShowSearch/renderSearch 过滤为 searchColumns。
  - 通过 v-model 将搜索表单值与组件内部 form 同步；支持外部传入 search.value 覆盖默认值。
- 搜索与重置
  - searchAction：重置页码为 1，触发 fetch；随后派发 search 事件携带 form/page/table 等上下文。
  - searchReset：重置页码与表单值为初始值（immutableSearchValue），触发 fetch 并派发 searchReset 事件。
- 请求与分页
  - fetch：将 page.current/page.size 与 form 合并作为请求参数；支持 formatCurrent 自定义分页参数格式；通过 customRequest 发起请求。
  - 分页组件 Page 的页码/页大小变更会触发 search，从而重新请求。
- 状态管理
  - 内部维护 loading、page、total、searchForm、immutableSearchValue 等状态；通过计算属性 form 控制 v-model 的读写。

```mermaid
classDiagram
class ProTable {
+props : columns, request, map, hide, search, form, table, pageSize
+data : loading, page, total, searchForm, immutableSearchValue
+computed : searchColumns, form, proData
+methods : search(), searchAction(), searchReset(), fetch(), pageSizeChange()
}
class ProSearch {
+props : columns, modelValue, position, searchLineNum, upDown
+events : search, reset
+methods : search(), reset(), upDownHandle()
}
ProTable --> ProSearch : "内嵌并绑定"
```

**图表来源**
- [ProTable.vue:154-851](file://packages/components/ProTable.vue#L154-L851)
- [ProSearch.vue:114-218](file://packages/components/ProSearch.vue#L114-L218)

**章节来源**
- [ProTable.vue:154-851](file://packages/components/ProTable.vue#L154-L851)
- [ProTable.d.ts:1-59](file://types/ProTable.d.ts#L1-L59)

### 列级搜索配置与渲染
- 基本字段
  - 未设置 renderSearch 时，默认使用 Input。
- 自定义控件
  - renderSearch.type 指定控件类型；props 传递控件属性；format 用于格式化输出值。
  - 特殊场景：renderSearch.format 支持包装对象（如日期范围），或通过函数格式化字符串。
- 条件控制
  - notShowSearch 控制列是否出现在搜索区。
  - renderSearch 可以是函数，动态返回控件（如 Select）。
- 示例参考
  - 日期范围（daterange）、布尔开关（Switch）、远程下拉（ProSelect）等。

**章节来源**
- [ProTable 示例页面:36-44](file://src/views/ProTable.vue#L36-L44)
- [ProTable 示例页面:185-188](file://src/views/ProTable.vue#L185-L188)
- [ProTable 示例页面:236-243](file://src/views/ProTable.vue#L236-L243)
- [ProSearch 示例页面:22-54](file://src/views/ProSearch.vue#L22-L54)

### 搜索重置与状态管理
- 初始值保留
  - 组件挂载时保存外部传入的 search.value 为 immutableSearchValue，重置时以此为准恢复。
- 重置流程
  - 重置页码与表单值；触发 fetch；派发 searchReset 事件；若存在表单弹窗，同步重置内部表单。
- 交互保障
  - loading 期间禁用重置按钮；enter 键触发搜索；支持 beforeSearch/beforeReset 钩子。

**章节来源**
- [ProTable.vue:433-434](file://packages/components/ProTable.vue#L433-L434)
- [ProTable.vue:636-648](file://packages/components/ProTable.vue#L636-L648)
- [ProSearch.vue:172-189](file://packages/components/ProSearch.vue#L172-L189)

### 高级搜索与复杂条件
- 复杂条件组合
  - 通过 renderSearch.format 包装数组/对象，形成“起止时间”“区间值”等复合条件。
  - 使用 renderSearch.rules 定义校验规则（如必填、数组字段校验）。
- 搜索历史与建议
  - 当前仓库未提供搜索历史持久化与自动补全功能；可在外部业务侧维护历史列表并通过 v-model 初始化到 search.value 实现“最近一次”或“常用条件”的快速应用。
- 动态控件
  - renderSearch 支持函数返回控件，结合远程数据源（如 request）实现联动下拉、级联选择等。

**章节来源**
- [ProTable 示例页面:190-205](file://src/views/ProTable.vue#L190-L205)
- [ProTable 示例页面:103-131](file://src/views/ProTable.vue#L103-L131)

### 与 ProForm 的协同
- 表单弹窗中的搜索
  - ProTable 内部可通过 ProForm 弹窗承载新增/编辑场景；搜索重置不会影响弹窗表单，但可调用 resetForm 手动重置。
- 表单与搜索的联动
  - 可在 search.value 中预置部分字段，使弹窗表单与搜索条件保持一致的默认值。

**章节来源**
- [ProTable.vue:649-654](file://packages/components/ProTable.vue#L649-L654)
- [ProForm 示例页面:1-198](file://src/views/ProForm.vue#L1-L198)

## 依赖关系分析
- 组件耦合
  - ProTable 依赖 ProSearch 作为搜索区；二者通过事件与 v-model 解耦。
  - ProTable 依赖 request.js 进行网络请求；request.js 支持字符串/对象/函数三种请求形式。
- 外部依赖
  - ViewUI Plus 提供基础 UI 组件（Form、Input、Button、Page 等）。
  - Lodash-es 提供深拷贝、取值、映射、判断等工具方法。
  - Day.js 在示例中用于日期格式化（通过 format 函数）。

```mermaid
graph LR
PT["ProTable.vue"] --> PS["ProSearch.vue"]
PT --> REQ["request.js"]
PS --> LO["lodash-es"]
PT --> LO
PT --> DAY["dayjs(示例中使用)"]
PT --> VUE["Vue3"]
PS --> VUE
REQ --> AX["axios"]
```

**图表来源**
- [ProTable.vue:156-165](file://packages/components/ProTable.vue#L156-L165)
- [ProSearch.vue:115-117](file://packages/components/ProSearch.vue#L115-L117)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [main.js:1-14](file://src/main.js#L1-L14)

**章节来源**
- [ProTable.vue:156-165](file://packages/components/ProTable.vue#L156-L165)
- [ProSearch.vue:115-117](file://packages/components/ProSearch.vue#L115-L117)
- [request.js:1-78](file://packages/libs/request.js#L1-L78)
- [main.js:1-14](file://src/main.js#L1-L14)

## 性能考虑
- 搜索防抖
  - 对于高频输入（如文本框）建议在外层业务侧增加防抖策略，避免频繁触发请求。
- 折叠搜索区
  - 大量搜索字段时启用折叠，减少 DOM 渲染压力。
- 合理的分页参数
  - 使用 formatCurrent 自定义分页参数，避免一次性加载过多数据。
- 请求合并
  - 将多个搜索字段合并为一个对象，减少请求体体积；必要时仅发送变更字段。
- 缓存策略
  - 对于远程下拉（ProSelect）等，建议在业务层缓存选项列表，降低重复请求。

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

## 故障排查指南
- 搜索无响应
  - 检查 request 是否正确配置；确认 fetch 是否被调用；查看控制台是否有网络错误。
- 重置无效
  - 确认是否正确使用 immutableSearchValue；确保 reset 流程中恢复了 form 与 page。
- 格式化失败
  - renderSearch.format 的表达式需确保可执行且返回期望格式；注意日期格式化函数的依赖。
- 校验不生效
  - renderSearch.rules 需要与控件类型匹配；数组字段校验需指定 fields 与 trigger。

**章节来源**
- [ProTable.vue:665-741](file://packages/components/ProTable.vue#L665-L741)
- [ProTable.vue:636-648](file://packages/components/ProTable.vue#L636-L648)
- [ProTable 示例页面:190-205](file://src/views/ProTable.vue#L190-L205)

## 结论
ProTable 与 ProSearch 的组合提供了灵活、可扩展的搜索与筛选能力：通过列级配置即可快速定义搜索控件，借助 ProTable 的状态管理与请求封装，实现一键搜索、重置与分页联动。对于更复杂的业务需求（如历史记录、自动补全、多维条件组合），可在外部业务层进行增强，同时遵循性能与体验的最佳实践。

[本节为总结性内容，不直接分析具体文件]

## 附录

### 常见配置清单与示例路径
- ProTable 搜索区配置
  - 位置与初始值：参考 [ProTable 示例页面:89-96](file://src/views/ProTable.vue#L89-L96)
  - 列级搜索字段定义：参考 [ProTable 示例页面:36-44](file://src/views/ProTable.vue#L36-L44)、[ProTable 示例页面:185-188](file://src/views/ProTable.vue#L185-L188)
- ProSearch 高级用法
  - 日期范围与格式化：参考 [ProSearch 示例页面:26-36](file://src/views/ProSearch.vue#L26-L36)、[ProTable 示例页面:39-43](file://src/views/ProTable.vue#L39-L43)
  - 动态控件与校验：参考 [ProTable 示例页面:236-243](file://src/views/ProTable.vue#L236-L243)、[ProTable 示例页面:190-205](file://src/views/ProTable.vue#L190-L205)
- 请求与分页
  - 请求封装与参数抽取：参考 [request.js:39-77](file://packages/libs/request.js#L39-L77)
  - 分页联动与重置：参考 [ProTable.vue:613-618](file://packages/components/ProTable.vue#L613-L618)、[ProTable.vue:636-648](file://packages/components/ProTable.vue#L636-L648)

**章节来源**
- [ProTable 示例页面:36-44](file://src/views/ProTable.vue#L36-L44)
- [ProTable 示例页面:89-96](file://src/views/ProTable.vue#L89-L96)
- [ProSearch 示例页面:26-36](file://src/views/ProSearch.vue#L26-L36)
- [request.js:39-77](file://packages/libs/request.js#L39-L77)
- [ProTable.vue:613-618](file://packages/components/ProTable.vue#L613-L618)
- [ProTable.vue:636-648](file://packages/components/ProTable.vue#L636-L648)