---
trigger: manual
---

# Popup 功能实现指南

## 概述

Popup 是系统中常用的 UI 组件，用于在当前页面上显示一个浮层，通常用于显示额外信息、表单或选择器等。本指南将详细介绍如何在系统中实现 Popup 功能。

## 技术栈

系统使用的是基于 Taro 的 React 框架，Popup 组件来自 `@nutui/nutui-react-taro` 库。

## 基本用法

### 1. 导入 Popup 组件

```tsx
import { Popup } from "@nutui/nutui-react-taro";
```

### 2. 基本属性

Popup 组件常用属性包括：

- `visible`: 控制 Popup 是否显示（boolean）
- `position`: Popup 出现的位置（"top" | "bottom" | "left" | "right" | "center"）
- `title`: Popup 标题
- `onClose`: 关闭时的回调函数
- `onOverlayClick`: 点击遮罩层时的回调函数
- `closeable`: 是否显示关闭按钮
- `round`: 是否显示圆角
- `lockScroll`: 是否锁定背景滚动

### 3. 基本结构

```tsx
<Popup
  visible={visible}
  position="bottom"
  title="Popup 标题"
  onClose={() => setVisible(false)}
  closeable
  round
  lockScroll
>
  <View>Popup 内容</View>
</Popup>
```

## 实现步骤

### 1. 状态管理

在组件中定义控制 Popup 显示/隐藏的状态：

```tsx
const [visible, setVisible] = useState(false);
```

### 2. 触发 Popup 显示

通过事件触发 Popup 显示，例如点击按钮：

```tsx
<Button onClick={() => setVisible(true)}>打开 Popup</Button>
```

### 3. Popup 内容实现

Popup 内容根据具体需求实现，可以包含表单、列表、文本等。

### 4. 关闭 Popup

Popup 可以通过以下方式关闭：
- 点击关闭按钮（如果设置了 `closeable`）
- 点击遮罩层（如果未阻止）
- 调用 `onClose` 回调函数
- 在 Popup 内部通过按钮等操作手动设置 visible 为 false

## 常见使用场景

### 1. 选择器

常用于实现各种选择器，如经销商选择、供应商选择等：

```tsx
<Popup
  visible={visible}
  position="bottom"
  title="选择经销商"
  onClose={() => setVisible(false)}
>
  <View>经销商列表</View>
</Popup>
```

### 2. 表单编辑

用于编辑某一项信息：

```tsx
<Popup
  visible={visible}
  position="bottom"
  title={`编辑${supplier.name}销售单价`}
  onClose={() => setVisible(false)}
>
  <View className="flex flex-col gap-3 p-2.5">
    <Input
      placeholder="请输入销售单价"
      type="digit"
      value={price}
      onChange={(value) => setPrice(value)}
    />
    <Button onClick={handleSave}>保存</Button>
  </View>
</Popup>
```

### 3. 确认弹窗

用于确认操作：

```tsx
<Popup
  visible={visible}
  position="bottom"
  title="确认操作"
  onClose={() => setVisible(false)}
>
  <View className="p-4">
    <View className="mb-4">确定要执行此操作吗？</View>
    <View className="flex gap-2">
      <Button onClick={() => setVisible(false)}>取消</Button>
      <Button onClick={handleConfirm}>确认</Button>
    </View>
  </View>
</Popup>
```

## 最佳实践

### 1. 状态管理

- 使用 useState 管理 Popup 的显示状态
- 对于复杂场景，可以使用 useReducer 或状态管理库

### 2. 性能优化

- 对于内容较多的 Popup，考虑使用懒加载
- 在 Popup 关闭时清理相关状态

### 3. 用户体验

- 合理设置 Popup 的位置和大小
- 提供明确的关闭方式
- 添加适当的动画效果

### 4. 样式统一

- 保持 Popup 标题、按钮等样式与系统一致
- 使用系统定义的颜色和间距变量

## 注意事项

1. 确保在组件卸载时清理相关状态和副作用
2. 注意 Popup 内容的可访问性
3. 避免同时显示多个 Popup
4. 考虑移动端的适配问题
5. 在 Popup 关闭时重置相关表单数据（如需要）

## 示例代码

```tsx
import { Popup, Button, View } from "@nutui/nutui-react-taro";
import { useState } from "react";

export default function MyComponent() {
  const [visible, setVisible] = useState(false);
  
  return (
    <View>
      <Button onClick={() => setVisible(true)}>打开 Popup</Button>
      
      <Popup
        visible={visible}
        position="bottom"
        title="示例 Popup"
        onClose={() => setVisible(false)}
        closeable
        round
      >
        <View className="p-4">
          <View>这是 Popup 内容</View>
          <Button 
            block 
            type="primary" 
            className="mt-4"
            onClick={() => setVisible(false)}
          >
            关闭
          </Button>
        </View>
      </Popup>
    </View>
  );
}
```
