Skip to content
On this page

Picker/PickerPopup/PickerView 选择器

注:

Import

js
import { TaPicker, TaPickerPopup, TaPickerView } from 'tantalum-ui-mobile'

具体的引入方式可以参考引入组件

Import Type

组件导出的类型定义:

ts
import type {
  CascaderOnSelect,
  PickerOnConfirm,
  PickerFieldNames,
  SelectorOnChange,
  SelectorModelValue,
  PickerDetail,
  SelectorValueParser,
  SelectorValueFormatter,
  VisibleState,
  PopupOnVisibleStateChange,
  PopupOnCancel
} from 'tantalum-ui-mobile'

公共 Props

属性类型默认值必填说明
v-modelSelectorModelValue[]选中值
optionsOptions[]数据集
field-namesPickerFieldNames{ label: 'label', value: 'value', children: 'children' }自定义 options 中 label value children 的字段 key
formatterSelectorValueFormatterparser 成对设置,对于 v-model 和 change 的值进行转化
parserSelectorValueParserformatter 成对设置,对于 v-model 和 change 的值进行反转化

Options 的结构

组件会通过 options 值的结构来分析是否是级联模式。

判断是级联的方式是:一维数组且子数据中有 children 列表。

单列

js
const options = [2016, 2017, 2018, 2019, 2020]

或者完整写法:

js
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
  }
]

多列

js
const options = [
  [2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020],
  ['', '', '', '']
]

级联

js
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
vue
<script setup lang="ts">
import { ref } from 'vue'
import { cascadeOptions, multiOptions, options, regionOptions } from './data'
import {
  showToast,
  showPicker,
  type SelectorModelValue,
  type SelectorValueFormatter,
  type SelectorValueParser
} from '@/index'

const regionValue = ref([])
const disableValue = ref([2000, ''])

const separator = '-'
const formatValue = ref(`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)
}
</script>

<script lang="ts">
export default {
  name: 'ExpPicker'
}
</script>

<template>
  <ta-group title="基础用法">
    <ta-cell label="单列">
      <ta-picker :options="options" @change="onChange"></ta-picker>
    </ta-cell>
    <ta-cell label="多列">
      <ta-picker :options="multiOptions" @change="onChange"></ta-picker>
    </ta-cell>
    <ta-cell label="级联">
      <ta-picker :options="cascadeOptions" @change="onChange"></ta-picker>
    </ta-cell>
    <ta-cell label="地区">
      <ta-picker
        :options="regionOptions"
        :fieldNames="{ value: 'label' }"
        v-model="regionValue"
        @change="onChange"
      />
    </ta-cell>
    <ta-cell label="formatter/parser">
      <ta-picker
        v-model="formatValue"
        :formatter="formatter"
        :parser="parser"
        :options="multiOptions"
        @change="onChange"
      ></ta-picker>
    </ta-cell>
    <ta-cell label="禁用">
      <ta-picker :modelValue="disableValue" :options="multiOptions" disabled />
    </ta-cell>
  </ta-group>
  <ta-group title="API">
    <ta-cell label="showPicker" isLink @click="onCallApi" />
  </ta-group>
</template>

Picker Props

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

Picker Events

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

PickerPopup 选择弹窗

vue
<script setup lang="ts">
import { ref } from 'vue'
import { multiOptions } from '../Picker/data'
import {
  showToast,
  type SelectorModelValue,
  type PickerOnConfirm,
  type PopupOnVisibleStateChange,
  type PopupOnCancel
} from '@/index'

const popupValue = ref([2000, ''])
const visible = ref(false)
const clickEvent = ref(false)
const changeEvent = ref(false)
const visibleEvent = ref(false)

const onVisibleStateChange: PopupOnVisibleStateChange = res => {
  if (visibleEvent.value) {
    console.log('visible-state-change', res)
    showToast(`${res.state} 事件触发`)
  }

  if (res.state === 'hidden') {
    clickEvent.value = false
    visibleEvent.value = false
    changeEvent.value = false
  }
}

const onConfirm: PickerOnConfirm = res => {
  if (clickEvent.value) {
    console.log('confirm', res)
    showToast(`点击确定按钮`)
  }
}

function onChange(res: SelectorModelValue) {
  if (changeEvent.value) {
    console.log('change', res)
    showToast(`值改为 ${res}`)
  }
}

const onCancel: PopupOnCancel = res => {
  if (clickEvent.value) {
    console.log('cancel', res)

    if (res.source === 'cancelClick') {
      showToast('点击了取消按钮')
    } else if (res.source === 'maskClick') {
      showToast('点击了蒙层')
    }
  }
}
</script>

<script lang="ts">
export default {
  name: 'ExpPickerPopup'
}
</script>

<template>
  <ta-notice-bar class="top-notice-bar" title="基础展示参数可以参考 Picker" />
  <ta-group title="基础用法">
    <ta-cell label="v-model" isLink @click="visible = true">{{ popupValue }}</ta-cell>
  </ta-group>
  <ta-group title="事件监听">
    <ta-cell
      label="change"
      isLink
      @click="
        () => {
          changeEvent = true
          visible = true
        }
      "
    />
    <ta-cell
      label="confirm/cancel"
      isLink
      @click="
        () => {
          clickEvent = true
          visible = true
        }
      "
    />
    <ta-cell
      label="visible-state-change"
      isLink
      @click="
        () => {
          visibleEvent = true
          visible = true
        }
      "
    />
  </ta-group>
  <ta-picker-popup
    v-model:visible="visible"
    title="PickerPopup"
    :options="multiOptions"
    v-model="popupValue"
    @change="onChange"
    @confirm="onConfirm"
    @cancel="onCancel"
    @visibleStateChange="onVisibleStateChange"
  />
</template>

PickerPopup Props

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

PickerPopup Events

事件描述回调函数参数函数 TypeScript
confirm点击确定按钮后触发payload: PickerDetailPickerOnConfirm
cancel点击取消按钮后触发PopupOnCancel
change选中值发生变化时触发payload: SelectorModelValueSelectorOnChange
visible-state-change展示隐藏时触发payload: { state: VisibleState }PopupOnVisibleStateChange

VisibleState 值说明

说明备注
show展示时触发
shown展示且动画结束后触发
hide隐藏时触发可能携带其他参数 cancel, maskClick, closeClick 等
hidden隐藏且动画结束后触发可能携带其他参数 cancel, maskClick, closeClick 等

PickerView 选择面板

vue
<script setup lang="ts">
import { ref } from 'vue'
import { showToast, type SelectorModelValue } from '@/index'
import { cascadeOptions, multiOptions, options } from '../Picker/data'

const colValue = ref([2001])
const multiValue = ref([])
const cascadeValue = ref([])
const changeValue = ref([])

function onChange(res: SelectorModelValue) {
  console.log('change', res)
}

function onChangeEvent(res: SelectorModelValue) {
  onChange(res)

  showToast(`change: ${res}`)
}
</script>

<script lang="ts">
export default {
  name: 'ExpPickerView'
}
</script>

<template>
  <ta-notice-bar class="top-notice-bar" title="基础展示参数可以参考 Picker" />
  <ta-group title="单列">
    <ta-picker-view :options="options" @change="onChange" v-model="colValue"></ta-picker-view>
  </ta-group>
  <ta-group title="多列">
    <ta-picker-view
      :options="multiOptions"
      @change="onChange"
      v-model="multiValue"
    ></ta-picker-view>
  </ta-group>
  <ta-group title="级联">
    <ta-picker-view
      :options="cascadeOptions"
      @change="onChange"
      v-model="cascadeValue"
    ></ta-picker-view>
  </ta-group>
  <ta-group title="change 事件">
    <ta-picker-view
      :options="multiOptions"
      @change="onChangeEvent"
      v-model="changeValue"
    ></ta-picker-view>
  </ta-group>
</template>

PickerView Events

事件描述回调函数参数函数 TypeScript
change滑动后选中值发生变化时触发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 调用

js
showPicker({
  title: 'Picker',
  options: multiOptions,
  success: ({ confirm, cancel, detail }) => {
    ...
  }
})

类型释义

SelectorValue

ts
type SelectorValue = string | number | Date

SelectorModelValue

ts
type SelectorModelValue = SelectorValue | SelectorValue[]

注:在不自定义 formatter/parser 的情况下,v-model 只有 (string | number)[] 这种情况。

PickerDetail

ts
interface PickerDetail {
  label: string
  value: (string | number)[]
}

PickerFieldNames

ts
interface PickerFieldNames {
  label?: string
  value?: string
  children?: string
}

SelectorValueFormatter

ts
interface SelectorValueFormatter {
  (valueArray: SelectorValue[], labelArray: string[]):
    | { value: SelectorModelValue; label: string }
    | SelectorModelValue
}

将 v-model 的原始值转为需要的自定义值,值需要满足 SelectorModelValue 的类型约束,可以返回 { value, label } 对两个数据进行修改,或者单独返回 value。

SelectorValueParser

ts
interface SelectorValueParser {
  (value: unknown): SelectorValue[]
}

SelectorValueFormatter 相反,将自定义 v-model 的值转为组件认识的原始数组。