---
name: "Swiper"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "0.5.10" }
title: "Swiper - 幻灯片、轮播容器，使用时必须指定整体高度"
---

## Swiper

> [VERSION] @ray-js/ray >= 0.5.10

### 描述

幻灯片／轮播容器，支持自动切换、衔接滑动与指示点；使用时需明确整体高度。

### 属性

| 属性 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `dots` | `boolean` | 否 | `false` | 是否显示面板指示点 |
| `dotColor` | `string` | 否 | `"rgba(0,0,0,0.3)"` | 指示点颜色 |
| `dotActiveColor` | `string` | 否 | `"#000"` | 当前选中的指示点颜色 |
| `autoplay` | `boolean` | 否 | `false` | 是否自动切换 |
| `current` | `number` | 否 | `0` | 当前所在滑块的 index |
| `interval` | `number` | 否 | `5000` | 自动切换时间间隔 |
| `duration` | `number` | 否 | `500` | 滑动动画时长 |
| `circular` | `boolean` | 否 | `false` | 是否采用衔接滑动 |
| `vertical` | `boolean` | 否 | `false` | 滑动方向是否为纵向 |
| `dataSource` | `I[]` | 否 | - | 列表数据，用于与 renderItem 组合渲染；泛型 I 会推断出每一项的数据类型。 也可不传 dataSource，直接以 SwiperItem 作为 children 渲染。 |
| `renderItem` | `(item: I, index: number) => any` | 否 | - | 渲染列表每一项，item 类型由 dataSource 的泛型 I 推断 |
| `onChange` | `(event: SwiperComponentChangeEvent) => void` | 否 | - | current 改变时触发 |
| `onAfterChange` | `(event: SwiperComponentAfterChangeEvent) => void` | 否 | - | 动画结束时触发 |

### 引用对象

##### `interface` SwiperComponentChangeEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `type` | `"change"` | 事件类型 |
| `current` | `number` | 当前滑块索引 |
| `source` | `"" \| "autoplay" \| "touch"` | 触发原因 |
| `detail` | `SwiperChangeDetail` | 事件数据 |

##### `interface` SwiperComponentAfterChangeEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `type` | `"afterChange"` | 事件类型 |
| `current` | `number` | 当前滑块索引 |
| `source` | `"" \| "autoplay" \| "touch"` | 触发原因 |
| `detail` | `SwiperChangeDetail` | 事件数据 |

##### `interface` SwiperChangeDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `current` | `number` | 当前滑块索引 |
| `currentItemId` | `string` | 当前滑块 id |
| `source` | `"" \| "autoplay" \| "touch"` | 触发原因 |

##### `interface` BaseEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `type` | `string` | 事件类型 |
| `timeStamp` | `number` | 页面打开到触发事件所经过的毫秒数 |
| `target` | `Target` | 触发事件的源组件 |
| `currentTarget` | `Target` | 当前组件的一些属性值集合 |
| `mark` | `any` | 事件标记数据 |

##### `interface` Target

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `id` | `string` | 事件源组件的id |
| `dataset` | `Record<string, unknown>` | 事件源组件上的 `dataset` 自定义属性组成的集合 |


### 示例代码

#### 基础用法

```tsx
import React, { useState } from 'react';
import { Swiper, SwiperItem, View, Button, Text } from '@ray-js/ray';

export default function BasicSwiper() {
  const [current, setCurrent] = useState(0);
  const colors = ['#1890ff', '#52c41a', '#faad14'];

  return (
    <View>
      <Swiper
        style={{ width: '702rpx', height: '200rpx' }}
        dots
        current={current}
        onChange={(e) => setCurrent(e.current)}
      >
        {colors.map((color, index) => (
          <SwiperItem key={index}>
            <View
              style={{
                width: '100%',
                height: '100%',
                backgroundColor: color,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
              }}
            >
              <Text style={{ color: '#fff' }}>第 {index + 1} 页</Text>
            </View>
          </SwiperItem>
        ))}
      </Swiper>
      <Button
        style={{ marginTop: '20rpx' }}
        onClick={() => setCurrent((current + 1) % 3)}
      >
        切换到第 {(current + 1) % 3 + 1} 页
      </Button>
    </View>
  );
}
```

#### 自动轮播与 dataSource

```tsx
import React, { useState } from 'react';
import { Swiper, View, Text } from '@ray-js/ray';

export default function AutoplaySwiper() {
  const [current, setCurrent] = useState(0);
  const dataSource = [
    { id: '1', color: '#1890ff', label: '轮播一' },
    { id: '2', color: '#52c41a', label: '轮播二' },
    { id: '3', color: '#faad14', label: '轮播三' },
  ];

  return (
    <Swiper
      style={{ width: '702rpx', height: '200rpx' }}
      autoplay
      interval={2500}
      circular
      dots
      current={current}
      dataSource={dataSource}
      renderItem={(item) => (
        <View
          style={{
            width: '100%',
            height: '100%',
            backgroundColor: item.color,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Text style={{ color: '#fff', fontSize: '32rpx' }}>{item.label}</Text>
        </View>
      )}
      onChange={(e) => setCurrent(e.current)}
    />
  );
}
```

#### 纵向轮播与指示点颜色

```tsx
import React, { useState } from 'react';
import { Swiper, View, Text } from '@ray-js/ray';

export default function VerticalSwiper() {
  const [current, setCurrent] = useState(0);
  const dataSource = [
    { id: '1', color: '#722ed1', label: '纵向一' },
    { id: '2', color: '#eb2f96', label: '纵向二' },
    { id: '3', color: '#13c2c2', label: '纵向三' },
  ];

  return (
    <Swiper
      style={{ width: '702rpx', height: '300rpx' }}
      vertical
      dots
      dotColor="rgba(255,255,255,0.4)"
      dotActiveColor="#fff"
      duration={400}
      current={current}
      dataSource={dataSource}
      renderItem={(item) => (
        <View
          style={{
            width: '100%',
            height: '100%',
            backgroundColor: item.color,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Text style={{ color: '#fff', fontSize: '32rpx' }}>{item.label}</Text>
        </View>
      )}
      onChange={(e) => setCurrent(e.current)}
      onAfterChange={(e) => console.log('动画结束:', e.current)}
    />
  );
}
```
