Picker/PickerPopup/PickerView 选择器

注:

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

属性类型默认值必填说明
valueSelectorModelValue[]选中值
optionsOptions[]数据集
fieldNamesPickerFieldNames{ label: 'label', value: 'value', children: 'children' }自定义 options 中 label value children 的字段 key
formatterSelectorValueFormatterparser 成对设置,对于 value 的值进行转化
parserSelectorValueParserformatter 成对设置,对于 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

属性类型默认值必填说明
namestring标识
placeholderstring没有选中值的提示,也会用在弹窗标题上
disabledbooleanfalse是否禁用

Picker Events

事件描述回调函数参数函数 TypeScript
onChange选择后选中值发生变化时触发payload: SelectorModelValueSelectorOnChange

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

属性类型默认值必填说明
visiblebooleanfalse是否显示弹窗
titlestring弹窗标题

PickerPopup Events

事件描述回调函数参数函数 TypeScript
onConfirm点击确定按钮后触发payload: PickerDetailPickerOnConfirm
onCancel点击取消按钮后触发PopupOnCancel
onChange选中值发生变化时触发payload: SelectorModelValueSelectorOnChange
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: SelectorModelValueSelectorOnChange

showPicker(object) 显示选择弹窗

object

属性类型默认值必填说明
titlestring弹窗标题
value(string | number)[][]选中值
optionsOptions[]数据集
fieldNamesPickerFieldNames{ 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 的值转为组件认识的原始数组。