---
nav:
  title: 组件
  order: 1
group:
  title: 基础组件
  order: 1
title: PisellGridPro
order: 1
category: pro
---

# PisellGridPro 页面布局

PisellGridPro 是一个强大的页面布局组件，为后台管理系统提供标准的页面结构和布局能力，帮助开发者快速搭建规范统一的页面。

## 设计理念

在后台管理系统中，大部分页面都遵循相似的布局结构：顶部标题栏、工具栏、数据概览、主内容区、底部操作栏。PisellGridPro 将这些常见的布局模块进行了标准化封装，提供了以下能力:

- **标准化布局**：统一的页面结构，保证视觉一致性
- **灵活组合**：各个子组件可按需使用，支持灵活布局
- **开箱即用**：内置常用布局模式，减少重复代码
- **响应式设计**：自适应不同屏幕尺寸
- **高度可定制**：支持自定义样式和内容

## 布局结构

```
┌─────────────────────────────────────────────┐
│  Header                                     │
│  (标题、徽章、副标题、操作按钮)                │
├─────────────────────────────────────────────┤
│  ToolBar                                    │
│  (标签页、筛选器、排序等)                      │
├─────────────────────────────────────────────┤
│  DataCard                                   │
│  (统计数据卡片)                               │
├─────────────────────────────────────────────┤
│  View                                       │
│  (主内容区，自带滚动)                          │
│                                             │
│                                             │
├─────────────────────────────────────────────┤
│  Footer                                     │
│  (底部操作栏、分页等)                          │
└─────────────────────────────────────────────┘
```

## 核心子组件

### PisellGridPro.Header - 页头组件

页面顶部标题栏，包含标题、徽章、副标题和操作按钮。

### PisellGridPro.ToolBar - 工具栏组件

灵活的工具栏组件，支持标签页和四个位置的内容区域。

### PisellGridPro.DataCard - 数据卡片组件

用于展示统计数据的卡片组件，支持趋势显示。

### PisellGridPro.View - 内容视图组件

主内容区域，内置滚动能力。

### PisellGridPro.Footer - 页脚组件

页面底部操作栏。

## 基础使用

### 简单页面布局

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

export default () => {
  return (
    <PisellGridPro>
      <PisellGridPro.Header title="页面标题" />
      <PisellGridPro.View>
        <div>主内容区域</div>
      </PisellGridPro.View>
    </PisellGridPro>
  );
};
```

### 完整页面布局

```tsx
import { PisellGridPro } from '@pisell/materials';
import { Button, Badge } from 'antd';

export default () => {
  return (
    <PisellGridPro>
      {/* 页头 */}
      <PisellGridPro.Header
        title="订单管理"
        badge={<Badge count={5} />}
        subTitle="管理所有订单信息"
        actionsList={
          <>
            <Button type="primary">创建订单</Button>
            <Button>导出</Button>
          </>
        }
      />

      {/* 工具栏 */}
      <PisellGridPro.ToolBar
        topLeft={<div>筛选器</div>}
        topRight={<div>排序</div>}
        bottomLeft={<div>批量操作</div>}
        bottomRight={<div>视图切换</div>}
      />

      {/* 数据卡片 */}
      <PisellGridPro.DataCard
        dataItems={[
          {
            key: '1',
            title: '总订单数',
            value: '1,234',
            compareValue: '+12%',
            trend: 'up',
          },
          {
            key: '2',
            title: '待处理',
            value: '56',
            compareValue: '-5',
            trend: 'down',
          },
        ]}
      />

      {/* 内容区 */}
      <PisellGridPro.View>
        <div>订单列表内容</div>
      </PisellGridPro.View>

      {/* 页脚 */}
      <PisellGridPro.Footer>
        <div>分页组件</div>
      </PisellGridPro.Footer>
    </PisellGridPro>
  );
};
```

### 带标签页的布局

```tsx
import { PisellGridPro } from '@pisell/materials';
import { Tabs } from 'antd';

export default () => {
  return (
    <PisellGridPro>
      <PisellGridPro.Header title="商品管理" />

      <PisellGridPro.ToolBar
        tabs={
          <Tabs
            items={[
              { key: '1', label: '全部商品' },
              { key: '2', label: '已上架' },
              { key: '3', label: '已下架' },
            ]}
          />
        }
        topRight={<div>搜索框</div>}
      />

      <PisellGridPro.View>
        <div>商品列表</div>
      </PisellGridPro.View>
    </PisellGridPro>
  );
};
```

### 数据统计页面

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

export default () => {
  const statsData = [
    {
      key: 'revenue',
      title: '总收入',
      value: '$45,231',
      compareValue: '+20%',
      trend: 'up' as const,
      comparePrefix: '较上月',
    },
    {
      key: 'orders',
      title: '订单数',
      value: '2,340',
      compareValue: '+180',
      trend: 'up' as const,
    },
    {
      key: 'customers',
      title: '新客户',
      value: '573',
      compareValue: '-12',
      trend: 'down' as const,
    },
    {
      key: 'conversion',
      title: '转化率',
      value: '68.2%',
      compareValue: '+2.5%',
      trend: 'up' as const,
    },
  ];

  return (
    <PisellGridPro>
      <PisellGridPro.Header title="数据概览" subTitle="实时数据统计" />

      <PisellGridPro.DataCard dataItems={statsData} />

      <PisellGridPro.View>
        <div>图表内容</div>
      </PisellGridPro.View>
    </PisellGridPro>
  );
};
```

### 可点击的数据卡片

```tsx
import { PisellGridPro } from '@pisell/materials';
import { message } from 'antd';

export default () => {
  const handleCardClick = (cardKey: string) => {
    message.info(`点击了 ${cardKey} 卡片`);
  };

  return (
    <PisellGridPro>
      <PisellGridPro.Header title="业务概览" />

      <PisellGridPro.DataCard
        dataItems={[
          {
            key: 'total',
            title: '总销售额',
            value: '$126,560',
            compareValue: '+12.5%',
            trend: 'up',
            onClick: () => handleCardClick('总销售额'),
          },
          {
            key: 'today',
            title: '今日销售',
            value: '$8,846',
            compareValue: '+8.2%',
            trend: 'up',
            onClick: () => handleCardClick('今日销售'),
          },
        ]}
      />

      <PisellGridPro.View>
        <div>详细内容</div>
      </PisellGridPro.View>
    </PisellGridPro>
  );
};
```

## API

### PisellGridPro Props

| 参数      | 说明       | 类型            | 默认值 | 必填 |
| --------- | ---------- | --------------- | ------ | ---- |
| className | 自定义类名 | `string`        | -      | ❌   |
| style     | 自定义样式 | `CSSProperties` | -      | ❌   |
| children  | 子组件     | `ReactNode`     | -      | ✅   |

### Header Props

| 参数        | 说明           | 类型            | 默认值 | 必填 |
| ----------- | -------------- | --------------- | ------ | ---- |
| title       | 页面标题       | `ReactNode`     | -      | ❌   |
| badge       | 标题旁边的徽章 | `ReactNode`     | -      | ❌   |
| subTitle    | 副标题         | `ReactNode`     | -      | ❌   |
| actionsList | 右侧操作按钮   | `ReactNode`     | -      | ❌   |
| className   | 自定义类名     | `string`        | -      | ❌   |
| style       | 自定义样式     | `CSSProperties` | -      | ❌   |

### ToolBar Props

| 参数        | 说明         | 类型            | 默认值 | 必填 |
| ----------- | ------------ | --------------- | ------ | ---- |
| tabs        | 标签页内容   | `ReactNode`     | -      | ❌   |
| topLeft     | 顶部左侧内容 | `ReactNode`     | -      | ❌   |
| topRight    | 顶部右侧内容 | `ReactNode`     | -      | ❌   |
| bottomLeft  | 底部左侧内容 | `ReactNode`     | -      | ❌   |
| bottomRight | 底部右侧内容 | `ReactNode`     | -      | ❌   |
| className   | 自定义类名   | `string`        | -      | ❌   |
| style       | 自定义样式   | `CSSProperties` | -      | ❌   |

### DataCard Props

| 参数      | 说明             | 类型             | 默认值 | 必填 |
| --------- | ---------------- | ---------------- | ------ | ---- |
| dataItems | 统计卡片数据列表 | `StatCardItem[]` | `[]`   | ❌   |
| className | 自定义类名       | `string`         | -      | ❌   |
| style     | 自定义样式       | `CSSProperties`  | -      | ❌   |

### StatCardItem

| 参数          | 说明             | 类型             | 默认值       | 必填 |
| ------------- | ---------------- | ---------------- | ------------ | ---- |
| key           | 唯一标识         | `string`         | -            | ✅   |
| title         | 卡片标题         | `ReactNode`      | -            | ✅   |
| value         | 主要数值         | `ReactNode`      | -            | ✅   |
| compareValue  | 对比数值         | `ReactNode`      | -            | ❌   |
| trend         | 对比趋势         | `'up' \| 'down'` | -            | ❌   |
| comparePrefix | 对比前缀文本     | `string`         | `'v.s. pre'` | ❌   |
| showCompare   | 是否显示对比信息 | `boolean`        | `true`       | ❌   |
| onClick       | 点击回调         | `() => void`     | -            | ❌   |
| className     | 自定义类名       | `string`         | -            | ❌   |
| style         | 自定义样式       | `CSSProperties`  | -            | ❌   |

### View Props

| 参数      | 说明       | 类型            | 默认值 | 必填 |
| --------- | ---------- | --------------- | ------ | ---- |
| className | 自定义类名 | `string`        | -      | ❌   |
| style     | 自定义样式 | `CSSProperties` | -      | ❌   |
| children  | 子组件     | `ReactNode`     | -      | ✅   |

### Footer Props

| 参数      | 说明       | 类型            | 默认值 | 必填 |
| --------- | ---------- | --------------- | ------ | ---- |
| className | 自定义类名 | `string`        | -      | ❌   |
| style     | 自定义样式 | `CSSProperties` | -      | ❌   |
| children  | 子组件     | `ReactNode`     | -      | ✅   |

## 典型应用场景

### 1. 列表页面

```
<PisellGridPro>
  <PisellGridPro.Header title="用户列表" />
  <PisellGridPro.ToolBar
    topLeft={<SearchBar />}
    topRight={<FilterButton />}
  />
  <PisellGridPro.View>
    <UserTable />
  </PisellGridPro.View>
  <PisellGridPro.Footer>
    <Pagination />
  </PisellGridPro.Footer>
</PisellGridPro>
```

### 2. 数据统计页面

```
<PisellGridPro>
  <PisellGridPro.Header title="销售统计" />
  <PisellGridPro.DataCard dataItems={statsData} />
  <PisellGridPro.View>
    <Charts />
  </PisellGridPro.View>
</PisellGridPro>
```

### 3. 详情页面

```
<PisellGridPro>
  <PisellGridPro.Header
    title="订单详情"
    actionsList={<Button>编辑</Button>}
  />
  <PisellGridPro.View>
    <OrderDetail />
  </PisellGridPro.View>
  <PisellGridPro.Footer>
    <Button>取消</Button>
    <Button type="primary">保存</Button>
  </PisellGridPro.Footer>
</PisellGridPro>
```

### 4. 工作台页面

```
<PisellGridPro>
  <PisellGridPro.Header
    title="工作台"
    subTitle="欢迎回来"
  />
  <PisellGridPro.DataCard dataItems={dashboardData} />
  <PisellGridPro.ToolBar
    tabs={<Tabs items={tabItems} />}
  />
  <PisellGridPro.View>
    <DashboardContent />
  </PisellGridPro.View>
</PisellGridPro>
```

## 样式定制

### 自定义主容器样式

```
<PisellGridPro
  style={{
    background: '#f5f5f5',
    padding: '0 32px',
  }}
>
  {/* 子组件 */}
</PisellGridPro>
```

### 自定义子组件样式

```
<PisellGridPro>
  <PisellGridPro.Header
    className="custom-header"
    style={{ borderBottom: '2px solid #1890ff' }}
    title="自定义样式"
  />

  <PisellGridPro.View
    style={{ background: '#fff', padding: '24px' }}
  >
    <div>内容</div>
  </PisellGridPro.View>
</PisellGridPro>
```

### 自定义数据卡片样式

```
<PisellGridPro.DataCard
  dataItems={[
    {
      key: '1',
      title: '自定义样式',
      value: '1,234',
      style: {
        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
        color: '#fff',
      },
    },
  ]}
/>
```

## 扩展开发

如果你需要开发新的布局模式或扩展现有功能，请参考：

- [设计文档](./PisellGridPro.$tab-design.md)
- [开发文档](./PisellGridPro.$tab-dev.md)

## 注意事项

1. **布局顺序**: 建议按照 Header → ToolBar → DataCard → View → Footer 的顺序使用子组件
2. **高度控制**: PisellGridPro 默认占满视口高度（100vh），View 组件会自动占据剩余空间
3. **滚动区域**: 只有 View 组件内部可滚动，其他组件固定不滚动
4. **性能优化**: View 组件使用了 PisellScrollView，会自动处理滚动性能问题
5. **响应式**: 组件支持响应式布局，会自动适配不同屏幕尺寸
6. **可选组件**: 所有子组件都是可选的，可以按需组合使用

## 最佳实践

### 1. 统一布局规范

在团队中统一使用 PisellGridPro 作为页面布局基础，保证视觉一致性。

```
// Good: 统一的布局结构
<PisellGridPro>
  <PisellGridPro.Header title="页面标题" />
  <PisellGridPro.View>内容</PisellGridPro.View>
</PisellGridPro>

// Bad: 自定义不一致的布局
<div className="custom-layout">
  <div className="header">页面标题</div>
  <div className="content">内容</div>
</div>
```

### 2. 合理使用数据卡片

数据卡片适合展示关键指标，不宜放置过多卡片。

```
// Good: 3-6 个核心指标
<PisellGridPro.DataCard
  dataItems={[
    { key: '1', title: '总收入', value: '$45,231' },
    { key: '2', title: '订单数', value: '2,340' },
    { key: '3', title: '转化率', value: '68.2%' },
  ]}
/>

// Bad: 过多卡片影响视觉
<PisellGridPro.DataCard dataItems={tenCards} />
```

### 3. 灵活使用 ToolBar

ToolBar 提供了 4 个位置，合理分配功能区域。

```
<PisellGridPro.ToolBar
  topLeft={<SearchBar />}        // 左侧：搜索、筛选
  topRight={<Button>创建</Button>} // 右侧：操作按钮
  bottomLeft={<BatchActions />}   // 底部左侧：批量操作
  bottomRight={<ViewSwitch />}    // 底部右侧：视图切换
/>
```

### 4. 页脚用于固定操作

Footer 适合放置分页、批量操作确认等固定在底部的元素。

```
<PisellGridPro.Footer>
  <div style={{ display: 'flex', justifyContent: 'space-between' }}>
    <div>已选择 10 项</div>
    <Pagination total={100} />
  </div>
</PisellGridPro.Footer>
```

### 5. View 内容区域的组织

View 组件内应该是主要的业务内容，保持内容区域的简洁。

```tsx
import { PisellGridPro } from '@pisell/materials';
import { Table } from 'antd';

const data = [
  { key: '1', name: '示例一', count: 1 },
  { key: '2', name: '示例二', count: 2 },
];
const columns = [
  { title: '名称', dataIndex: 'name' },
  { title: '数量', dataIndex: 'count' },
];

export default () => (
  <PisellGridPro.View>
    <Table dataSource={data} columns={columns} />
    {/* 或其他业务组件 */}
  </PisellGridPro.View>
);
```

## 常见问题

### 1. 如何实现全屏布局？

PisellGridPro 默认就是全屏布局（100vh）。

### 2. 如何让某个子组件占据剩余空间？

View 组件会自动占据剩余空间，无需额外配置。

### 3. 如何隐藏某个子组件？

直接不渲染该子组件即可。

```
<PisellGridPro>
  <PisellGridPro.Header title="标题" />
  {/* 不需要 ToolBar 就不渲染 */}
  <PisellGridPro.View>内容</PisellGridPro.View>
</PisellGridPro>
```

### 4. 如何自定义内边距？

通过 style 属性自定义。

```
<PisellGridPro style={{ padding: '0 32px' }}>
  {/* 子组件 */}
</PisellGridPro>
```

### 5. DataCard 为空时会怎样？

当 dataItems 为空数组时，DataCard 不会渲染任何内容。
