---
nav:
  title: 组件
  order: 1
group:
  title: 基础组件
  order: 1
title: PisellBasicGrid
order: 1
category: atom
---

# PisellBasicGrid 基础布局

基于 Flexbox 的基础布局组件，主要用于控制循环型数据组件的排列方式。提供了灵活的布局配置能力，包括排列方向、换行控制、间距设置、对齐方式等。

## 何时使用

- 需要控制循环型数据组件的排列方式时
- 需要一行显示 N 个元素时
- 需要等分容器宽度时
- 需要控制元素间距和对齐方式时
- 在低代码平台中需要可视化配置布局时

## 代码演示

### 基础用法

最简单的用法，横向排列子元素。

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

export default () => {
  return (
    <PisellBasicGrid>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>项目 1</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>项目 2</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>项目 3</div>
    </PisellBasicGrid>
  );
};
```

### 一行 N 个

通过设置 `columns` 属性，控制一行显示的元素个数。

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

export default () => {
  return (
    <PisellBasicGrid columns={4} gap={16} wrap="wrap">
      {Array.from({ length: 8 }).map((_, index) => (
        <div
          key={index}
          style={{
            padding: '16px',
            background: '#f0f0f0',
            textAlign: 'center',
          }}
        >
          项目 {index + 1}
        </div>
      ))}
    </PisellBasicGrid>
  );
};
```

### 等分布局

设置 `equalWidth` 为 `true`，子元素会等分容器宽度。

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

export default () => {
  return (
    <PisellBasicGrid equalWidth gap={12}>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>按钮 1</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>按钮 2</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>按钮 3</div>
    </PisellBasicGrid>
  );
};
```

### 竖向排列

通过设置 `direction="vertical"`，实现竖向排列。

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

export default () => {
  return (
    <PisellBasicGrid direction="vertical" gap={16}>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>表单项 1</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>表单项 2</div>
      <div style={{ padding: '16px', background: '#f0f0f0' }}>表单项 3</div>
    </PisellBasicGrid>
  );
};
```

### 数据源模式

使用 `dataSource` 和 `renderItem` 进行数据驱动渲染，适合低代码平台使用。

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

export default () => {
  const products = [
    { id: 1, name: '商品 1', price: 99 },
    { id: 2, name: '商品 2', price: 199 },
    { id: 3, name: '商品 3', price: 299 },
    { id: 4, name: '商品 4', price: 399 },
  ];

  return (
    <PisellBasicGrid
      columns={4}
      gap={16}
      wrap="wrap"
      dataSource={products}
      rowKey="id"
      renderItem={(item) => (
        <div
          style={{
            padding: '16px',
            background: '#f0f0f0',
            textAlign: 'center',
          }}
        >
          <div>{item.name}</div>
          <div style={{ color: '#ff4d4f', marginTop: '8px' }}>
            ¥{item.price}
          </div>
        </div>
      )}
    />
  );
};
```

### 主轴对齐

通过 `justify` 属性控制子元素在主轴上的对齐方式。

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

export default () => {
  return (
    <div>
      <h3>start（起始对齐）</h3>
      <PisellBasicGrid justify="start" gap={8}>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 1</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 2</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 3</div>
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>center（居中对齐）</h3>
      <PisellBasicGrid justify="center" gap={8}>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 1</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 2</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 3</div>
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>between（两端对齐）</h3>
      <PisellBasicGrid justify="between" gap={8}>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 1</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 2</div>
        <div style={{ padding: '8px', background: '#f0f0f0' }}>项目 3</div>
      </PisellBasicGrid>
    </div>
  );
};
```

### 交叉轴对齐

通过 `align` 属性控制子元素在交叉轴上的对齐方式。

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

export default () => {
  return (
    <div>
      <h3>start（顶部对齐）</h3>
      <PisellBasicGrid align="start" gap={8} style={{ height: '100px' }}>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '40px' }}>
          项目 1
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '60px' }}>
          项目 2
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '80px' }}>
          项目 3
        </div>
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>center（居中对齐）</h3>
      <PisellBasicGrid align="center" gap={8} style={{ height: '100px' }}>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '40px' }}>
          项目 1
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '60px' }}>
          项目 2
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '80px' }}>
          项目 3
        </div>
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>end（底部对齐）</h3>
      <PisellBasicGrid align="end" gap={8} style={{ height: '100px' }}>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '40px' }}>
          项目 1
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '60px' }}>
          项目 2
        </div>
        <div style={{ padding: '8px', background: '#f0f0f0', height: '80px' }}>
          项目 3
        </div>
      </PisellBasicGrid>
    </div>
  );
};
```

### 间距控制

支持统一间距和分别设置行列间距。

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

export default () => {
  return (
    <div>
      <h3>统一间距（gap）</h3>
      <PisellBasicGrid columns={3} gap={16} wrap="wrap">
        {Array.from({ length: 6 }).map((_, index) => (
          <div
            key={index}
            style={{
              padding: '16px',
              background: '#f0f0f0',
              textAlign: 'center',
            }}
          >
            项目 {index + 1}
          </div>
        ))}
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>分别设置（rowGap + columnGap）</h3>
      <PisellBasicGrid columns={3} rowGap={24} columnGap={16} wrap="wrap">
        {Array.from({ length: 6 }).map((_, index) => (
          <div
            key={index}
            style={{
              padding: '16px',
              background: '#f0f0f0',
              textAlign: 'center',
            }}
          >
            项目 {index + 1}
          </div>
        ))}
      </PisellBasicGrid>
    </div>
  );
};
```

### 换行控制

通过 `wrap` 属性控制子元素是否换行。

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

export default () => {
  return (
    <div>
      <h3>nowrap（不换行）</h3>
      <PisellBasicGrid wrap="nowrap" gap={8}>
        {Array.from({ length: 10 }).map((_, index) => (
          <div
            key={index}
            style={{
              padding: '8px 16px',
              background: '#f0f0f0',
              whiteSpace: 'nowrap',
            }}
          >
            标签 {index + 1}
          </div>
        ))}
      </PisellBasicGrid>

      <h3 style={{ marginTop: '24px' }}>wrap（换行）</h3>
      <PisellBasicGrid wrap="wrap" gap={8}>
        {Array.from({ length: 10 }).map((_, index) => (
          <div
            key={index}
            style={{
              padding: '8px 16px',
              background: '#f0f0f0',
            }}
          >
            标签 {index + 1}
          </div>
        ))}
      </PisellBasicGrid>
    </div>
  );
};
```

### 自定义样式

支持通过 `className` 和 `style` 自定义样式。

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

export default () => {
  return (
    <PisellBasicGrid
      columns={3}
      gap={16}
      wrap="wrap"
      className="custom-grid"
      style={{
        padding: '20px',
        background: '#fafafa',
        borderRadius: '8px',
      }}
    >
      {Array.from({ length: 6 }).map((_, index) => (
        <div
          key={index}
          style={{
            padding: '16px',
            background: '#fff',
            borderRadius: '4px',
            textAlign: 'center',
          }}
        >
          项目 {index + 1}
        </div>
      ))}
    </PisellBasicGrid>
  );
};
```

## API

### PisellBasicGrid

| 参数         | 说明               | 类型                                                                               | 默认值         | 版本  |
| ------------ | ------------------ | ---------------------------------------------------------------------------------- | -------------- | ----- |
| children     | 子元素             | `ReactNode`                                                                        | -              | 1.0.0 |
| className    | 自定义类名         | `string`                                                                           | -              | 1.0.0 |
| style        | 自定义样式         | `CSSProperties`                                                                    | -              | 1.0.0 |
| direction    | 排列方向           | `'horizontal' \| 'horizontal-reverse' \| 'vertical' \| 'vertical-reverse'`         | `'horizontal'` | 1.0.0 |
| wrap         | 换行控制           | `'nowrap' \| 'wrap' \| 'wrap-reverse'`                                             | `'nowrap'`     | 1.0.0 |
| columns      | 一行显示的元素个数 | `number`                                                                           | -              | 1.0.0 |
| equalWidth   | 是否等分容器宽度   | `boolean`                                                                          | `false`        | 1.0.0 |
| gap          | 统一间距           | `number \| string`                                                                 | -              | 1.0.0 |
| rowGap       | 行间距             | `number \| string`                                                                 | -              | 1.0.0 |
| columnGap    | 列间距             | `number \| string`                                                                 | -              | 1.0.0 |
| justify      | 主轴对齐方式       | `'start' \| 'end' \| 'center' \| 'between' \| 'around' \| 'evenly'`                | `'start'`      | 1.0.0 |
| align        | 交叉轴对齐方式     | `'start' \| 'end' \| 'center' \| 'stretch' \| 'baseline'`                          | `'stretch'`    | 1.0.0 |
| alignContent | 多行对齐方式       | `'start' \| 'end' \| 'center' \| 'between' \| 'around' \| 'stretch'`               | `'stretch'`    | 1.0.0 |
| dataSource   | 数据源数组         | `T[]`                                                                              | -              | 1.0.0 |
| renderItem   | 渲染函数           | `(item: T, index: number) => ReactNode`                                            | -              | 1.0.0 |
| rowKey       | 指定每项的唯一 key | `string \| ((item: T, index: number) => string)`                                   | -              | 1.0.0 |
| responsive   | 响应式配置（预留） | `Record<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl', Partial<ResponsiveConfig>>` | -              | 1.0.0 |

## 注意事项

1. **columns 与 equalWidth 的优先级**：当同时设置 `columns` 和 `equalWidth` 时，`columns` 优先级更高，`equalWidth` 会被忽略。

2. **dataSource 与 children 的优先级**：当同时传入 `dataSource` 和 `children` 时，`dataSource` 优先级更高，`children` 会被忽略。

3. **gap 的单位**：当 `gap` 为数字类型时，默认单位为 `px`；也可以传入带单位的字符串，如 `"1rem"`、`"10%"` 等。

4. **rowGap/columnGap 优先级**：当同时设置 `gap` 和 `rowGap`/`columnGap` 时，`rowGap`/`columnGap` 优先级更高。

5. **columns 计算**：设置 `columns` 时，组件会自动计算子元素宽度，并考虑 `gap` 的影响，使用公式：`calc((100% - gap * (N-1)) / N)`。

6. **dataSource 为空数组**：当 `dataSource` 为空数组 `[]` 时，组件不会渲染任何内容。

7. **dataSource 为 undefined**：当 `dataSource` 为 `undefined` 时，组件会渲染 `children`。

8. **响应式功能**：当前版本的 `responsive` 属性为预留接口，暂不实现，后续版本迭代。

9. **无 UI 样式**：组件不包含任何 UI 样式，仅提供布局能力，具体样式需要由业务场景自定义。

## FAQ

### 如何实现一行显示 4 个元素？

使用 `columns` 属性：

```
<PisellBasicGrid columns={4} gap={16} wrap="wrap">
  {items.map((item) => (
    <div key={item.id}>{item.name}</div>
  ))}
</PisellBasicGrid>
```

### 如何实现等分布局？

使用 `equalWidth` 属性：

```
<PisellBasicGrid equalWidth gap={12}>
  <Button>取消</Button>
  <Button type="primary">确定</Button>
</PisellBasicGrid>
```

### 如何使用数据源模式？

传入 `dataSource` 和 `renderItem`：

```
<PisellBasicGrid
  columns={4}
  gap={16}
  dataSource={products}
  rowKey="id"
  renderItem={(item) => <ProductCard data={item} />}
/>
```

### 如何设置不同的行间距和列间距？

使用 `rowGap` 和 `columnGap`：

```
<PisellBasicGrid rowGap={24} columnGap={16}>
  {/* ... */}
</PisellBasicGrid>
```

### 如何实现竖向排列？

设置 `direction="vertical"`：

```
<PisellBasicGrid direction="vertical" gap={16}>
  <FormItem label="用户名" />
  <FormItem label="密码" />
  <FormItem label="邮箱" />
</PisellBasicGrid>
```

### 如何实现两端对齐？

设置 `justify="between"`：

```
<PisellBasicGrid justify="between" wrap="wrap">
  {/* ... */}
</PisellBasicGrid>
```

### columns 和 equalWidth 可以同时使用吗？

不建议同时使用。当同时设置时，`columns` 优先级更高，`equalWidth` 会被忽略。

### dataSource 为空数组时会渲染什么？

当 `dataSource` 为空数组 `[]` 时，组件不会渲染任何内容。如果需要显示空状态，可以在外部处理：

```
{dataSource.length === 0 ? (
  <Empty description="暂无数据" />
) : (
  <PisellBasicGrid dataSource={dataSource} renderItem={...} />
)}
```
