Cascader/CascaderPopup/CascaderView 级联选择

注:

Import

import {
  TaCascader,
  TaCascaderPopup,
  TaCascaderView
} from 'tantalum-ui-mobile-react'

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

Import Type

组件导出的类型定义:

import type {
  CascaderOnConfirm,
  CascaderFieldNames,
  SelectorOnChange,
  SelectorModelValue,
  CascaderDetail,
  SelectorValueParser,
  SelectorValueFormatter,
  VisibleState,
  PopupOnVisibleStateChange,
  PopupOnCancel
} from 'tantalum-ui-mobile-react'

公共 Props

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

Options 的结构

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

Cascader 级联选择器

注:

  • 支持表单,具体可参考 Form
import { cascadeOptions, regionOptions } from '../Picker/data'
import {
  showToast,
  showCascader,
  SelectorModelValue,
  SelectorValueFormatter,
  SelectorValueParser,
  TaGroup,
  TaCell,
  TaCascader
} from '@/index'
import { useState } from 'react'

const separator = '-'
const placeholder = '选择家电'

export default function ExpCascader() {
  const [disableValue] = useState(['bingxiang', 'sanmen'])
  const [formatValue] = useState(`bingxiang${separator}duikaimen`)

  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() {
    showCascader({
      options: cascadeOptions
    }).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="家电">
          <TaCascader
            options={cascadeOptions}
            onChange={onChange}
            placeholder={placeholder}
          />
        </TaCell>
        <TaCell label="地区">
          <TaCascader
            options={regionOptions}
            fieldNames={{ value: 'label' }}
            onChange={onChange}
          />
        </TaCell>
        <TaCell label="formatter/parser">
          <TaCascader
            value={formatValue}
            formatter={formatter}
            parser={parser}
            options={cascadeOptions}
            onChange={onChange}
          ></TaCascader>
        </TaCell>
        <TaCell label="禁用">
          <TaCascader
            value={disableValue}
            options={cascadeOptions}
            disabled
            onChange={onChange}
          />
        </TaCell>
      </TaGroup>
      <TaGroup title="API">
        <TaCell label="showCascader" isLink onClick={() => onCallApi()} />
      </TaGroup>
    </>
  )
}

Cascader Props

属性类型默认值必填说明
namestring标识
placeholderstring没有选中值的提示
disabledbooleanfalse是否禁用

Cascader Events

事件描述回调函数参数函数 TypeScript
onChange选择后 value 发生改变时触发payload: SelectorModelValueSelectorOnChange
onSelect选择后触发payload: CascaderDetailCascaderOnSelect

CascaderPopup 级联选择弹窗

import { cascadeOptions } from '../Picker/data'
import {
  showToast,
  SelectorModelValue,
  PickerOnConfirm,
  PopupOnVisibleStateChange,
  PopupOnCancel,
  TaCell,
  TaGroup,
  TaNoticeBar,
  TaCascader
} from '@/index'
import { useRef, useState } from 'react'

interface showArgs {
  visibleEvent?: boolean
  changeEvent?: boolean
  clickEvent?: boolean
}

export default function ExpCascaderPopup() {
  const [popupValue, setPopupValue] = useState(['bingxiang', 'duikaimen'])
  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[])
  }

  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="基础展示参数可以参考 Cascader"
      />
      <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>
      <TaCascader.Popup
        visible={visible}
        options={cascadeOptions}
        value={popupValue}
        onChange={onChange}
        onConfirm={onConfirm}
        onCancel={onCancel}
        onVisibleStateChange={onVisibleStateChange}
        onUpdateVisible={v => setVisible(v)}
      />
    </>
  )
}

CascaderPopup Props

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

CascaderPopup Events

事件描述回调函数参数函数 TypeScript
onConfirm点击确定按钮后触发payload: CascaderDetailCascaderOnConfirm
onCancel点击蒙层关闭后触发PopupOnCancel
onChange选中值发生变化时触发payload: SelectorModelValueSelectorOnChange
onVisibleStateChange展示隐藏时触发payload: { state: VisibleState }PopupOnVisibleStateChange
onUpdateVisible展示隐藏时触发visible: boolean 是否显示

VisibleState 值说明

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

CascaderView 级联选择面板

import {
  TaCascader,
  TaNoticeBar,
  TaGroup,
  showToast,
  SelectorModelValue,
  CascaderOnSelect
} from '@/index'
import { cascadeOptions } from '../Picker/data'

export default function ExpCascaderView() {
  function onChange(res: SelectorModelValue) {
    console.log('change', res)

    showToast(`change: ${res}`)
  }

  const onSelect: CascaderOnSelect = res => {
    console.log('select', res)

    showToast(`select: ${res.value}`)
  }

  return (
    <>
      <TaNoticeBar
        className="top-notice-bar"
        title="基础展示参数可以参考 Cascader"
      />
      <TaGroup title="家电">
        <TaCascader.View options={cascadeOptions} v-model="baseValue" />
      </TaGroup>
      <TaGroup title="空数据">
        <TaCascader.View options={[]} />
      </TaGroup>
      <TaGroup title="change 事件">
        <TaCascader.View options={cascadeOptions} onChange={onChange} />
      </TaGroup>
      <TaGroup title="select 事件(跟 change 的区别是重复选一样的也触发)">
        <TaCascader.View options={cascadeOptions} onSelect={onSelect} />
      </TaGroup>
    </>
  )
}

CascaderView Events

事件描述回调函数参数函数 TypeScript
onChange选择完毕后发生变化时触发payload: SelectorModelValueSelectorOnChange
onSelect每次选择完毕时触发payload: CascaderDetailCascaderOnSelect

showCascader(object) 显示级联选择弹窗

object

属性类型默认值必填说明
optionsOptions[]数据集
value(string | number)[][]选中值
fieldNamesCascaderFieldNames{ 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?CascaderDetail

Usage

具体调用方式可以参考API 调用

showCascader({
  title: '植物',
  options: cascadeOptions,
  success: ({ confirm, cancel, detail }) => {
    ...
  }
})

类型释义

SelectorValue

type SelectorValue = string | number | Date

SelectorModelValue

type SelectorModelValue = SelectorValue | SelectorValue[]

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

CascaderDetail

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

CascaderFieldNames

interface CascaderFieldNames {
  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 的值转为组件认识的原始数组。