Picker
A wheel picker that selects one value per column.
Usage
Popup, Inline, and Dense Rows
v-model:visible controls the popup, popup="false" renders inline, and itemHeight / visibleItemCount size the rows.
Loading demo...
Best Practices
- Keep
modelValuea complete array ordered likecolumns; sparse arrays are normalized, but explicit values keep form state auditable. - Give each column a
keywhen columns reorder or render conditionally, so Vue doesn't reuse an old column for different data. - Use stable primitive option
values and put display text inlabel. - Use inline mode (
popup=false) for always-visible settings, and the popup for mobile or short tasks. - Don't submit disabled values: the component skips disabled options only when it normalizes or recovers a scroll.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | PickerValue | [] | One value per column; missing or invalid values fall back to the first enabled option. |
columns | PickerColumn[] | [] | Column definitions, left to right. |
visible | boolean | false | Popup visibility, bound with v-model:visible. |
popup | boolean | true | true teleports a bottom popup; false renders inline. |
title | string | '' | Toolbar title. |
showToolbar | boolean | true | Shows the cancel, title, and confirm toolbar. |
confirmText | string | 'Confirm' | Confirm button text. |
cancelText | string | 'Cancel' | Cancel button text. |
disabled | boolean | false | Disables the toolbar, the options, and dragging. |
itemHeight | number | 36 | Row height in px; at least 24. |
visibleItemCount | number | 5 | Visible rows; even counts round up to odd, at least 3. |
closeOnClickMask | boolean | true | Closes the popup when the mask is clicked. |
lazyMount | boolean | true | Mounts the popup body on first open. |
Events
| Event | Params | Description |
|---|---|---|
update:modelValue | (value: PickerValue) | Fires when turning a column changes its value. |
change | (value: PickerValue) | Fires together with update:modelValue. |
update:visible | (visible: boolean) | Fires on open and close. |
confirm | (value: PickerValue) | Fires with the current value on confirm, then closes. |
cancel | - | Fires on cancel, then closes. |
open | - | Fires on open. |
close | - | Fires on close. |
Exposed Methods
| Name | Type | Description |
|---|---|---|
open | () => void | Opens the popup by writing visible=true. |
close | () => void | Closes the popup. |
toggle | () => void | Toggles the popup. |
Types
type PickerValue = Array<string | number>
PickerColumn, one entry of columns:
| Field | Type | Description |
|---|---|---|
key | string | Optional stable key. |
options | PickerOption[] | The column's options. |
PickerOption, one entry of options:
| Field | Type | Description |
|---|---|---|
value | string | number | Primitive value emitted for the column. |
label | string | Visible text. |
disabled | boolean | Prevents selection; skipped by the normalization fallback. |
Overview
- Each column is a drum the component turns itself, not a native scroller; it handles the pointer, the wheel, clicks, and the keyboard.
- A drag tracks the pointer, then coasts on its release velocity and settles on the nearest enabled row with a cubic ease-out; the wheel settles 120ms after it stops.
- Under reduced motion a drag still tracks the pointer, but there is no coast and settling doesn't ease.
- When a controlled parent echoes back the value a column is already turning to, the column finishes its turn instead of being re-placed.
- Only the rows facing the viewer are drawn (11 at the default size, whatever the column length); each carries
aria-setsizeandaria-posinset, so screen readers see the full list.
Technologies
- Rows sit on the drum by
rotateXof their distance from the offset (defaults:r = 116px, a 17.6° step, a 348px perspective); rows skip hit testing, and a click resolves to its row by inverting the projection in closed form. - Source:
packages/tuffex/packages/components/src/picker/.
查看源码
packages/tuffex/packages/components/src/picker/index.ts