---
title: 开发文档
order: 3
category: pro
---

# PisellFind 组件开发文档

## 1. 组件基本信息

| 项目       | 内容                 |
|----------|--------------------|
| **组件名称** | PisellFind         |
| **组件版本** | 1.0.0              |
| **组件分类** | Plus Components    |
| **组件编号** | pcl_find_V1.0      |
| **依赖组件** | PisellLookup       |
| **技术栈**  | React + TypeScript |
| **开发日期** | 2026-02-02         |

## 2. 组件概述

### 2.1 组件定位

PisellFind 是基于 PisellLookup 的**"组件内查找模式"Plus 组件**，专门为已加载数据的查找场景提供优化的默认配置。

**核心特点：**

- ✅ 薄封装：基于 PisellLookup，复用所有交互能力
- ✅ 开箱即用：提供针对"组件内查找"的合理默认配置
- ✅ 纯 UI 组件：只负责搜索入口交互，不负责数据过滤逻辑
- ✅ 灵活可配：所有 PisellLookup 的配置都可覆盖

**与 PisellLookup 的关系：**

```
┌────────────────────────────────────┐
│         PisellLookup (Pro)         │
│     搜索交互协议组件（底层）         │
│  ────────────────────────────────  │
│  • 定义交互协议                     │
│  • 管理搜索状态                     │
│  • 提供结果承载容器                 │
│  • 高度灵活，需要配置               │
└────────────────────────────────────┘
                ↑
                │ 继承和封装
                │
┌────────────────────────────────────┐
│          PisellFind (Plus)         │
│    组件内查找优化版本（上层）        │
│  ────────────────────────────────  │
│  • 提供合理的默认配置               │
│  • 专注"已加载数据查找"场景         │
│  • 开箱即用，降低使用成本           │
│  • 仍保持灵活性                    │
└────────────────────────────────────┘
```

### 2.2 设计理念

**为什么需要 PisellFind？**

虽然 PisellLookup 非常灵活强大，但在"组件内查找"这个特定场景下：

- ❌ 用户需要配置多个属性（triggerType、showConfirmButton、showHistory 等）
- ❌ 容易遗漏最佳实践配置
- ❌ 每次使用都要重复配置

**PisellFind 的价值：**

- ✅ 提供针对场景的默认配置
- ✅ 降低使用成本，开箱即用
- ✅ 统一"组件内查找"的交互体验
- ✅ 仍然保持所有灵活性（可覆盖任何配置）

### 2.3 核心价值

1. **开箱即用**：绑定 onSearch 即可使用
2. **最佳实践**：预设最适合"组件内查找"的配置
3. **降低门槛**：不需要了解所有 Lookup 的配置
4. **统一体验**：确保项目中所有查找功能交互一致

## 3. 组件需求点

### 3.1 功能需求

- [ ] 基于 PisellLookup 封装
- [ ] 提供合理的默认配置
- [ ] 透传所有 PisellLookup Props
- [ ] 透出 PisellLookup Ref
- [ ] 支持覆盖任何默认配置

### 3.2 默认配置需求

- [ ] triggerType 默认为 'button'
- [ ] showConfirmButton 默认为 false
- [ ] showHistory 默认为 true
- [ ] resultRender 默认为 undefined
- [ ] displayType 由 Lookup 智能判断（button→modal）

### 3.3 灵活性需求

- [ ] 支持切换为 input 模式
- [ ] 支持覆盖任何默认值
- [ ] 支持所有 PisellLookup 的配置
- [ ] 支持 Ref 方法调用

## 4. 组件 API 设计

### 4.1 Props 定义

```
interface PisellFindProps extends Omit<PisellLookupProps, 'never'> {
  // PisellFind 继承 PisellLookup 的所有 Props
  // 只是提供不同的默认值
}
```

**实际上 PisellFindProps 就是 PisellLookupProps**，只是默认值不同。

### 4.2 默认值

```
{
  triggerType: 'button',
  showConfirmButton: false,
  showHistory: true,
  resultRender: undefined,
  // 其他配置继承 PisellLookup 的默认值
}
```

### 4.3 Ref 方法

```
interface PisellFindRef = PisellLookupRef {
  open: () => void;
  close: () => void;
  getKeyword: () => string;
  setKeyword: (keyword: string) => void;
}
```

完全继承 PisellLookup 的 Ref 方法。

## 5. 组件模块拆解

### 5.1 组件结构

```
PisellFind
  └── PisellLookup（核心）
       ├── LookupTrigger（触发器）
       ├── LookupAuxiliary（辅助功能）
       └── LookupResultHost（结果承载）
```

PisellFind 本身不需要子组件，直接使用 PisellLookup。

### 5.2 文件结构

```
pisellFind/
  ├── index.tsx                     # 组件实现和导出（简单封装）
  ├── types.ts                      # TypeScript 类型定义（可选，使用 Lookup 的类型）
  ├── docs/                         # 文档目录
  │   ├── pisellFind.$tab-design.md # 设计文档（已有）
  │   ├── pisellFind.$tab-dev.md    # 开发文档（本文件）
  │   ├── pisellFind.$tab-test.md   # 测试文档
  │   └── pisellFind.md             # 使用文档
  └── .cursor/                      # 任务管理
      └── tasks.md                  # 任务清单
```

**注意：** PisellFind 不需要单独的样式文件、子组件、工具函数、Hooks，因为它直接使用 PisellLookup。

## 6. 组件实现方案

### 6.1 技术选型

| 技术项  | 选型              | 说明     |
|------|-----------------|--------|
| 基础组件 | PisellLookup    | 复用所有功能 |
| 封装方式 | forwardRef      | 透出 ref |
| 类型定义 | 继承 PisellLookup | 复用类型   |

### 6.2 核心实现

```
import React, { forwardRef } from 'react';
import { PisellLookup } from '../pisellLookup';
import type { PisellLookupProps, PisellLookupRef } from '../pisellLookup';

/**
 * PisellFind Props
 * 继承 PisellLookup 的所有 Props
 */
export type PisellFindProps = PisellLookupProps;

/**
 * PisellFind Ref
 * 继承 PisellLookup 的 Ref 方法
 */
export type PisellFindRef = PisellLookupRef;

/**
 * PisellFind 组件
 * 基于 PisellLookup 的组件内查找优化版本
 */
export const PisellFind = forwardRef<PisellFindRef, PisellFindProps>((props, ref) => {
  const {
    // 提取需要设置默认值的 Props
    triggerType = 'button',
    showConfirmButton = false,
    showHistory = true,
    ...restProps
  } = props;

  return (
    <PisellLookup
      ref={ref}
      triggerType={triggerType}
      showConfirmButton={showConfirmButton}
      showHistory={showHistory}
      {...restProps}
    />
  );
});

PisellFind.displayName = 'PisellFind';
```

### 6.3 默认配置说明

#### 6.3.1 triggerType='button'

**原因：** "组件内查找"通常是辅助功能，使用按钮触发不会干扰主界面布局。

**效果：**

- 页面上显示一个"搜索"按钮
- 点击按钮打开 Modal 搜索界面
- 适合列表页、表格页的顶部工具栏

**可配置：** 用户可以设置 `triggerType="input"` 切换为输入框模式。

#### 6.3.2 showConfirmButton=false

**原因：** "组件内查找"是对已加载数据的过滤，实时搜索更流畅。

**效果：**

- 输入框中不显示 Lookup 按钮
- 只显示清除按钮和扫码按钮
- 输入即触发搜索（带 300ms 防抖）

**可配置：** 用户可以设置 `showConfirmButton={true}` 显示确认按钮。

#### 6.3.3 showHistory=true

**原因：** "组件内查找"经常需要多次查找相同内容，历史记录提升效率。

**效果：**

- 自动保存搜索历史到 localStorage
- 打开搜索时显示历史记录
- 点击历史记录快速搜索

**可配置：** 用户可以设置 `showHistory={false}` 关闭历史。

#### 6.3.4 resultRender=undefined

**原因：** "组件内查找"的结果通常直接过滤页面上的列表/表格，不需要在弹窗中展示。

**效果：**

- 不在 Modal 中显示搜索结果
- 用户在 onSearch 回调中过滤数据
- 过滤后的列表/表格直接在页面上更新

**可配置：** 用户可以提供 `resultRender` 在弹窗中展示结果。

### 6.4 使用场景对比

#### 场景 1：列表页查找（默认配置）

```
使用 PisellFind：
<PisellFind
  onSearch={(keyword) => {
    const filtered = data.filter(item => item.name.includes(keyword));
    setFilteredData(filtered);
  }}
/>

等价于 PisellLookup：
<PisellLookup
  triggerType="button"
  showConfirmButton={false}
  showHistory={true}
  onSearch={(keyword) => {
    const filtered = data.filter(item => item.name.includes(keyword));
    setFilteredData(filtered);
  }}
/>
```

#### 场景 2：输入框模式（覆盖默认配置）

```
使用 PisellFind：
<PisellFind
  triggerType="input"
  onSearch={(keyword) => filterData(keyword)}
/>

等价于 PisellLookup：
<PisellLookup
  triggerType="input"
  showConfirmButton={false}
  showHistory={true}
  onSearch={(keyword) => filterData(keyword)}
/>
```

## 7. 组件依赖关系

```
PisellFind
  └── 依赖 PisellLookup
       ├── 依赖 Ant Design (Input, Button, Modal, Drawer 等)
       └── 依赖 PisellQRScanner/PisellScan（可选，扫码功能）
```

## 8. 开发计划

### 阶段一：类型定义 & 组件实现

- [ ] 编写 TypeScript 类型定义（复用 PisellLookup 类型）
- [ ] 实现 PisellFind 组件（薄封装）
- [ ] 透出 Ref

### 阶段二：测试 & 文档

- [ ] 编写单元测试
- [ ] 编写 Storybook 示例
- [ ] 编写使用文档
- [ ] 编写测试用例文档

### 阶段三：LowCode Meta

- [ ] 编写 LowCode Meta 配置
- [ ] 编写 Snippets 预设

### 阶段四：导出 & 集成

- [ ] 在主入口导出组件
- [ ] 验证功能
- [ ] 交付

## 9. 与 PisellLookup 的差异对比

| 维度         | PisellLookup (Pro) | PisellFind (Plus) |
|------------|--------------------|-------------------|
| **定位**     | 通用搜索交互协议组件         | 组件内查找专用组件         |
| **数据来源**   | 任意（外部接口、本地数据等）     | 本地已加载数据           |
| **默认触发器**  | input 输入框          | button 按钮         |
| **默认确认按钮** | 显示                 | 不显示（输入即搜索）        |
| **默认历史记录** | 不开启                | 开启                |
| **默认结果展示** | 需配置 resultRender   | 不展示（外部处理）         |
| **使用复杂度**  | 需要配置多个属性           | 开箱即用              |
| **适用场景**   | 所有搜索场景             | 已加载数据的查找场景        |
| **灵活性**    | 最高                 | 高（可覆盖所有配置）        |

## 10. 实现示例

### 10.1 最简单的实现

```
import React, { forwardRef } from 'react';
import { PisellLookup } from '../pisellLookup';
import type { PisellLookupProps, PisellLookupRef } from '../pisellLookup';

export type PisellFindProps = PisellLookupProps;
export type PisellFindRef = PisellLookupRef;

export const PisellFind = forwardRef<PisellFindRef, PisellFindProps>((props, ref) => {
  const {
    triggerType = 'button',
    showConfirmButton = false,
    showHistory = true,
    ...restProps
  } = props;

  return (
    <PisellLookup
      ref={ref}
      triggerType={triggerType}
      showConfirmButton={showConfirmButton}
      showHistory={showHistory}
      {...restProps}
    />
  );
});

PisellFind.displayName = 'PisellFind';
```

### 10.2 使用示例

#### 默认用法（Button + Modal）

```tsx
import { PisellFind } from '@pisell/materials';
import { useState } from 'react';
import { Table } from 'antd';

export default () => {
  const [data] = useState([
    { id: 1, name: 'iPhone 15 Pro', price: 7999 },
    { id: 2, name: 'MacBook Pro', price: 12999 },
  ]);
  const [filteredData, setFilteredData] = useState(data);
  const columns = [
    { title: '商品名称', dataIndex: 'name' },
    { title: '价格', dataIndex: 'price' },
  ];

  return (
    <div>
      <PisellFind
        onSearch={(keyword) => {
          const filtered = data.filter(item =>
            item.name.includes(keyword)
          );
          setFilteredData(filtered);
        }}
      />

      <Table dataSource={filteredData} columns={columns} />
    </div>
  );
};
```

#### 切换为 Input 模式

```tsx
import { PisellFind } from '@pisell/materials';

const filterData = (keyword: string) => {
  /* 在此根据 keyword 过滤数据并更新展示 */
};

export default () => (
  <PisellFind
    triggerType="input"
    placeholder="搜索商品"
    onSearch={(keyword) => filterData(keyword)}
  />
);
```

#### 使用 Ref 控制

```tsx
import { useRef } from 'react';
import { PisellFind, type PisellFindRef } from '@pisell/materials';

const filterData = (keyword: string) => {
  /* 在此根据 keyword 过滤数据并更新展示 */
};

export default () => {
  const findRef = useRef<PisellFindRef>(null);

  return (
    <div>
      <PisellFind
        ref={findRef}
        onSearch={(keyword) => filterData(keyword)}
      />
      {/* 外部控制: findRef.current?.open(); findRef.current?.close(); */}
    </div>
  );
};
```

## 11. 风险点与注意事项

### 11.1 技术风险

1. **依赖 PisellLookup**：必须确保 PisellLookup 已开发完成且稳定
2. **类型兼容性**：需要正确继承 PisellLookup 的类型

### 11.2 开发注意事项

1. **保持简单**：PisellFind 应该尽可能简单，只做默认配置
2. **完全透传**：除了默认值，其他所有 Props 都应透传
3. **Ref 透出**：必须透出 Lookup 的 ref
4. **文档说明**：需要清楚说明与 Lookup 的关系和使用场景

## 12. 总结

PisellFind 是一个**语义化的预设配置组件**：

- ✅ **职责清晰**：只负责提供默认配置，不添加新逻辑
- ✅ **实现简单**：约 30 行代码即可完成
- ✅ **易于维护**：依赖稳定的 PisellLookup
- ✅ **降低门槛**：用户无需了解所有配置即可使用
- ✅ **保持灵活**：用户仍可覆盖任何配置

通过 PisellFind，我们将"组件内查找"这个常见场景的最佳实践固化为组件，提升开发效率和交互一致性。
