Picker/PickerPopup/PickerView 选择器
注:
- 这 3 个组件是渐进式组件,可查看 渐进式组件 了解。
Import
import { TaPicker, TaPickerPopup, TaPickerView } from 'tantalum-ui-mobile-react'
具体的引入方式可以参考引入组件。
Import Type
组件导出的类型定义:
import type {
CascaderOnSelect,
PickerOnConfirm,
PickerFieldNames,
SelectorOnChange,
SelectorModelValue,
PickerDetail,
SelectorValueParser,
SelectorValueFormatter,
VisibleState,
PopupOnVisibleStateChange,
PopupOnCancel
} from 'tantalum-ui-mobile-react'
公共 Props
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
value | SelectorModelValue | [] | 否 | 选中值 |
options | Options | [] | 是 | 数据集 |
fieldNames | PickerFieldNames | { label: 'label', value: 'value', children: 'children' } | 否 | 自定义 options 中 label value children 的字段 key |
formatter | SelectorValueFormatter | 否 | 和 parser 成对设置,对于 value 的值进行转化 | |
parser | SelectorValueParser | 否 | 和 formatter 成对设置,对于 value 的值进行反转化 |
Options 的结构
组件会通过 options 值的结构来分析是否是级联模式。
判断是级联的方式是:一维数组且子数据中有 children 列表。
单列
const options = [2016, 2017, 2018, 2019, 2020]
或者完整写法:
const options = [
{
label: '2016',
value: 2016,
disabled: false
},
{
label: '2017',
value: 2017,
disabled: false
},
{
label: '2018',
value: 2018,
disabled: false
},
{
label: '2019',
value: 2019,
disabled: false
},
{
label: '2020',
value: 2020,
disabled: false
}
]
多列
const options = [
[2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020],
['春', '夏', '秋', '冬']
]
级联
const options = [
{
label: '空调',
value: 'kongtiao',
children: [
{
label: '家用空调',
value: 'jiayongkongtiao',
children: [
{
label: '挂式空调',
value: 'guashikongtiao'
},
{
label: '柜式空调',
value: 'guishikongtiao'
}
]
},
{
label: '厨房空调',
value: 'chufangkongtiao'
}
]
},
{
label: '冰箱',
value: 'bingxiang',
children: [
{
label: '双门',
value: 'shuangmen'
},
{
label: '三门',
value: 'sanmen'
}
]
}
]
Picker 选择器
注:
- 支持表单,具体可参考 Form。
import { cascadeOptions, multiOptions, options, regionOptions } from './data'
import {
showToast,
showPicker,
SelectorModelValue,
SelectorValueFormatter,
SelectorValueParser,
TaGroup,
TaCell,
TaPicker
} from '@/index'
import { useState } from 'react'
const separator = '-'
export default function ExpPicker() {
const [disableValue] = useState([2000, '春'])
const [formatValue] = useState(`2001${separator}夏`)
const formatter: SelectorValueFormatter = (valueArray, labelArray) => {
return {
value: valueArray.join(separator),
label: labelArray.join(separator)
}
}
const parser: SelectorValueParser = value => {
return value ? (value as string).split(separator) : []
}
function onCallApi() {
showPicker({
title: 'Picker',
options: multiOptions
}).then(res => {
console.log('success', res)
if (res.cancel) {
showToast('取消了')
} else {
showToast(`选择了 ${res.detail.label}`)
}
})
}
function onChange(res: SelectorModelValue) {
console.log('change', res)
}
return (
<>
<TaGroup title="基础用法">
<TaCell label="单列">
<TaPicker options={options} onChange={onChange} />
</TaCell>
<TaCell label="多列">
<TaPicker options={multiOptions} onChange={onChange} />
</TaCell>
<TaCell label="级联">
<TaPicker options={cascadeOptions} onChange={onChange} />
</TaCell>
<TaCell label="地区">
<TaPicker
options={regionOptions}
fieldNames={{ value: 'label' }}
onChange={onChange}
/>
</TaCell>
<TaCell label="formatter/parser">
<TaPicker
value={formatValue}
formatter={formatter}
parser={parser}
options={multiOptions}
onChange={onChange}
></TaPicker>
</TaCell>
<TaCell label="禁用">
<TaPicker
value={disableValue}
options={multiOptions}
disabled
onChange={onChange}
/>
</TaCell>
</TaGroup>
<TaGroup title="API">
<TaCell label="showPicker" isLink onClick={() => onCallApi()} />
</TaGroup>
</>
)
}
Picker Props
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
name | string | 否 | 标识 | |
placeholder | string | 否 | 没有选中值的提示,也会用在弹窗标题上 | |
disabled | boolean | false | 否 | 是否禁用 |
Picker Events
事件 | 描述 | 回调函数参数 | 函数 TypeScript |
---|---|---|---|
onChange | 选择后选中值发生变化时触发 | payload: SelectorModelValue | SelectorOnChange |
PickerPopup 选择弹窗
import { multiOptions } from '../Picker/data'
import {
showToast,
SelectorModelValue,
PickerOnConfirm,
PopupOnVisibleStateChange,
PopupOnCancel,
TaCell,
TaGroup,
TaNoticeBar,
TaPicker
} from '@/index'
import { useRef, useState } from 'react'
interface showArgs {
visibleEvent?: boolean
changeEvent?: boolean
clickEvent?: boolean
}
export default function ExpPickerPopup() {
const [popupValue, setPopupValue] = useState([2000, '夏'])
const [visible, setVisible] = useState(false)
const clickEvent = useRef(false)
const changeEvent = useRef(false)
const visibleEvent = useRef(false)
function onShow(args: showArgs = {}) {
visibleEvent.current = !!args.visibleEvent
changeEvent.current = !!args.changeEvent
clickEvent.current = !!args.clickEvent
setVisible(true)
}
const onVisibleStateChange: PopupOnVisibleStateChange = res => {
if (visibleEvent.current) {
console.log('onVisibleStateChange', res)
showToast(`${res.state} 事件触发`)
}
if (res.state === 'hidden') {
clickEvent.current = false
visibleEvent.current = false
changeEvent.current = false
}
}
const onConfirm: PickerOnConfirm = res => {
if (clickEvent.current) {
console.log('onConfirm', res)
showToast(`点击确定按钮`)
}
}
function onChange(res: SelectorModelValue) {
if (changeEvent.current) {
console.log('onChange', res)
showToast(`值改为 ${res}`)
}
setPopupValue(res as (string | number)[])
}
const onCancel: PopupOnCancel = res => {
if (clickEvent.current) {
console.log('onCancel', res)
if (res.source === 'cancelClick') {
showToast('点击了取消按钮')
} else if (res.source === 'maskClick') {
showToast('点击了蒙层')
}
}
}
return (
<>
<TaNoticeBar
className="top-notice-bar"
title="基础展示参数可以参考 Picker"
/>
<TaGroup title="基础用法">
<TaCell label="默认" isLink onClick={() => onShow({})}>
{popupValue}
</TaCell>
</TaGroup>
<TaGroup title="事件监听">
<TaCell
label="onChange"
isLink
onClick={() => onShow({ changeEvent: true })}
/>
<TaCell
label="onConfirm/onCancel"
isLink
onClick={() => onShow({ clickEvent: true })}
/>
<TaCell
label="onVisibleStateChange"
isLink
onClick={() => onShow({ visibleEvent: true })}
/>
</TaGroup>
<TaPicker.Popup
visible={visible}
title="PickerPopup"
options={multiOptions}
value={popupValue}
onChange={onChange}
onConfirm={onConfirm}
onCancel={onCancel}
onVisibleStateChange={onVisibleStateChange}
onUpdateVisible={v => setVisible(v)}
/>
</>
)
}
PickerPopup Props
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
visible | boolean | false | 否 | 是否显示弹窗 |
title | string | 否 | 弹窗标题 |
PickerPopup Events
事件 | 描述 | 回调函数参数 | 函数 TypeScript |
---|---|---|---|
onConfirm | 点击确定按钮后触发 | payload: PickerDetail | PickerOnConfirm |
onCancel | 点击取消按钮后触发 | PopupOnCancel | |
onChange | 选中值发生变化时触发 | payload: SelectorModelValue | SelectorOnChange |
onVisibleStateChange | 展示隐藏时触发 | payload: { state: VisibleState } | PopupOnVisibleStateChange |
onUpdateVisible | 展示隐藏时触发 | visible: boolean 是否显示 |
VisibleState 值说明
值 | 说明 | 备注 |
---|---|---|
show | 展示时触发 | |
shown | 展示且动画结束后触发 | |
hide | 隐藏时触发 | 可能携带其他参数 cancel, maskClick, closeClick 等 |
hidden | 隐藏且动画结束后触发 | 可能携带其他参数 cancel, maskClick, closeClick 等 |
PickerView 选择面板
import {
TaPicker,
TaNoticeBar,
TaGroup,
showToast,
SelectorModelValue
} from '@/index'
import { useState } from 'react'
import { cascadeOptions, multiOptions, options } from '../Picker/data'
export default function ExpPickerView() {
const [simpleValue, setSimpleValue] = useState([2001])
function onChange(res: SelectorModelValue) {
console.log('change', res)
}
function onChangeEvent(res: SelectorModelValue) {
onChange(res)
showToast(`change: ${res}`)
}
return (
<>
<TaNoticeBar
className="top-notice-bar"
title="基础展示参数可以参考 Picker"
/>
<TaGroup title="单列">
<TaPicker.View
value={simpleValue}
options={options}
onChange={v => setSimpleValue(v as number[])}
></TaPicker.View>
</TaGroup>
<TaGroup title="多列">
<TaPicker.View
options={multiOptions}
onChange={onChange}
></TaPicker.View>
</TaGroup>
<TaGroup title="级联">
<TaPicker.View
options={cascadeOptions}
onChange={onChange}
></TaPicker.View>
</TaGroup>
<TaGroup title="change 事件">
<TaPicker.View
options={multiOptions}
onChange={onChangeEvent}
></TaPicker.View>
</TaGroup>
</>
)
}
PickerView Events
事件 | 描述 | 回调函数参数 | 函数 TypeScript |
---|---|---|---|
onChange | 滑动后选中值发生变化时触发 | payload: SelectorModelValue | SelectorOnChange |
showPicker(object) 显示选择弹窗
object
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 否 | 弹窗标题 | |
value | (string | number)[] | [] | 否 | 选中值 |
options | Options | [] | 是 | 数据集 |
fieldNames | PickerFieldNames | { label: 'label', value: 'value', children: 'children' } | 否 | 自定义 options 中 label value children 的字段 key |
success | (payload: SuccessPayload) => void | 否 | 接口调用成功(在用户做出选择后,如取消,选择选项)的回调函数 | |
fail | (e: Error) => void | 否 | 接口调用失败(如传入错误的参数)的回调函数(不传入 fail 遇错误直接抛出) | |
complete | () => void | 否 | 弹窗关闭或调用失败的回调函数 |
SuccessPayload
属性 | 类型 | 说明 |
---|---|---|
confirm? | boolean | 为 true 时,表示点击了确定,此时返回 detail |
cancel? | boolean | 为 true 时,表示取消 |
detail? | PickerDetail |
Usage
具体调用方式可以参考API 调用。
showPicker({
title: 'Picker',
options: multiOptions,
success: ({ confirm, cancel, detail }) => {
...
}
})
类型释义
SelectorValue
type SelectorValue = string | number | Date
SelectorModelValue
type SelectorModelValue = SelectorValue | SelectorValue[]
注:在不自定义 formatter/parser
的情况下,value 只有 (string | number)[]
这种情况。
PickerDetail
interface PickerDetail {
label: string
value: (string | number)[]
}
PickerFieldNames
interface PickerFieldNames {
label?: string
value?: string
children?: string
}
SelectorValueFormatter
interface SelectorValueFormatter {
(valueArray: SelectorValue[], labelArray: string[]):
| { value: SelectorModelValue; label: string }
| SelectorModelValue
}
将 value 的原始值转为需要的自定义值,值需要满足 SelectorModelValue
的类型约束,可以返回 { value, label } 对两个数据进行修改,或者单独返回 value。
SelectorValueParser
interface SelectorValueParser {
(value: unknown): SelectorValue[]
}
跟 SelectorValueFormatter
相反,将自定义 value 的值转为组件认识的原始数组。