---
name: "Picker"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "0.5.10" }
title: "Picker - 从底部弹起的滚动选择器"
---

## Picker

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

### 描述

从底部弹起的滚动选择器，支持普通、多列、时间与日期四种模式。

### 属性

| 属性 | 类型 | 必填 | 默认值 | 最低版本 | 描述 |
| --- | --- | --- | --- | --- | --- |
| `name` | `string` | 否 | - | - | 表单控件名称，提交表单时作为键名 |
| `mode` | `"selector" \| "multiSelector" \| "time" \| "date"` | 否 | `"selector"` | - | 选择器类型selector：普通选择器；multiSelector：多列选择器；time：时间；date：日期 |
| `disabled` | `boolean` | 否 | `false` | - | 是否禁用 |
| `range` | `string \| number \| Record<string, unknown>[] \| string \| number \| Record<string, unknown>[][]` | 否 | `[]` | - | mode 为 selector 或 multiSelector 时有效，为单列或多列数据源 |
| `rangeKey` | `string` | 否 | `""` | - | 当 range 为对象数组时，指定用于展示文本的对象字段名 |
| `value` | `number \| number[] \| string` | 否 | `""` | - | 选中值：selector 为下标；multiSelector 为下标数组；time/date 为字符串，格式为"hh:mm"/"YYYY-MM-DD"； |
| `start` | `string` | 否 | `""` | - | mode 为 time 时表示有效时间范围开始，格式 hh:mm；mode 为 date 时为 YYYY-MM-DD |
| `end` | `string` | 否 | `""` | - | mode 为 time 时表示有效时间范围结束，格式 hh:mm；mode 为 date 时为 YYYY-MM-DD |
| `fields` | `"year" \| "month" \| "day"` | 否 | `"day"` | - | mode 为 date 时，粒度：年 / 月 / 日 |
| `cancelText` | `string` | 否 | `"取消"` | - | 取消按钮文案 |
| `confirmText` | `string` | 否 | `"确定"` | - | 确定按钮文案 |
| `onCancel` | `(event: PickerCancelEvent) => void` | 否 | - | `1.9.90` | 取消选择时触发 |
| `onChange` | `(event: PickerChangeEvent) => void` | 否 | - | - | 滚动选择器变更时触发（确定选择后） |
| `onColumnChange` | `(event: PickerColumnChangeEvent) => void` | 否 | - | - | 多列选择器某一列变更时触发 |

### 引用对象

##### `interface` PickerCancelEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `PickerCancelDetail` | 事件数据 |

##### `interface` PickerChangeEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `PickerChangeDetail` | 事件数据 |
| `value` | `number \| number[] \| string \| string[]` | 当前选中的值 |

##### `interface` PickerColumnChangeEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `PickerColumnChangeDetail` | 事件数据 |

##### `interface` PickerCancelDetail

```typescript
export interface PickerCancelDetail {
  [key: string]: unknown;
}
```

##### `interface` BaseEvent

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

##### `interface` PickerChangeDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `value` | `number \| number[] \| string \| string[]` | 当前选中的值 |

##### `interface` PickerColumnChangeDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `column` | `number` | 变更的列序号 |
| `value` | `number` | 变更的列当前值 |

##### `interface` Target

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


### 示例代码

#### 基础用法

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

export default function () {
  const [current, setCurrent] = React.useState(0);
  const range = ['美国', '中国', '巴西', '日本'];

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="selector"
        onChange={(e) => {
          console.log('选择器改变:', e.detail.value);
          setCurrent(e.detail.value);
        }}
        range={range}
        value={current}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前选择: {range[current]}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### 时间选择器

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

export default function () {
  const [time, setTime] = React.useState('12:00');

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="time"
        value={time}
        start="09:00"
        end="18:00"
        onChange={(e) => {
          console.log('时间改变:', e.detail.value);
          setTime(e.detail.value);
        }}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前时间: {time}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### 日期选择器

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

export default function () {
  const [date, setDate] = React.useState('2026-01-01');

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="date"
        value={date}
        start="2020-01-01"
        end="2030-12-31"
        fields="day"
        onChange={(e) => {
          console.log('日期改变:', e.detail.value);
          setDate(e.detail.value);
        }}
        onCancel={() => console.log('取消选择')}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前日期: {date}</Text>
        </View>
      </Picker>
    </View>
  );
}
```

#### 多列选择器

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

export default function () {
  const [value, setValue] = React.useState([0, 0]);
  const range = [
    ['广东', '浙江', '江苏'],
    ['广州', '杭州', '南京'],
  ];

  return (
    <View style={{ padding: '20px' }}>
      <Picker
        mode="multiSelector"
        range={range}
        value={value}
        disabled={false}
        confirmText="确定"
        cancelText="取消"
        onChange={(e) => {
          console.log('多列选择:', e.detail.value);
          setValue(e.detail.value);
        }}
        onColumnChange={(e) => console.log('列变更:', e.detail.column, e.detail.value)}
        onCancel={() => console.log('取消选择')}
      >
        <View style={{ padding: '10px', backgroundColor: '#f5f5f5' }}>
          <Text>当前选择: {range[0][value[0]]} - {range[1][value[1]]}</Text>
        </View>
      </Picker>
    </View>
  );
}
```
