级联选择组件可以搭配 Field 和 Popup 组件使用,示例如下:
import { Cascader, Field, Popup } from "@taroify/core"
import { ArrowRight } from "@taroify/icons"
import { useState } from "react"
const dept = [
{
label: "研发中心",
value: "1",
children: [
{
label: "产线1",
value: "1-1",
children: [
{
label: "研发",
value: "1-1-1",
},
{
label: "测试",
value: "1-1-2",
},
{
label: "产品",
value: "1-1-3",
}
]
},
{
label: "产线2",
value: "1-2",
}
]
},
{
label: "客户中心",
value: "2",
children: [
{
label: "客服",
value: "2-1",
},
{
label: "销售",
value: "2-2",
}
]
}
]
function BasicCascader() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState<string[]>([])
const [fieldValue, setFieldValue] = useState("")
return (
<>
<Field label="选项值" isLink onClick={() => setOpen(true)}>
<Input readonly placeholder="请选择部门" value={fieldValue} />
</Field>
<Popup open={open} rounded placement="bottom" onClose={setOpen}>
<Popup.Close />
<Cascader
options={dept}
value={value}
title="请选择部门"
placeholder="请选择"
onSelect={setValue}
onChange={(_values_, options) => {
setOpen(false)
setFieldValue(
options.map(item => item.children).join("/")
)
}}
/>
</Popup>
</>
)
}
通过 CSS 变量来设置选中状态的高亮颜色。
<Cascader className="custom-color" />
.custom-color {
--tabs-active-color: red;
--cascader-active-color: red;
}
通过loadData返回下一级的选项,返回空数组[]时结束触发onChange
export const dynamic = [
{
label: "产品",
value: "1"
},
{
label: "测试",
value: "2"
},
{
label: "研发",
value: "3"
}
]
function DynamicCascader() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState<string[]>([])
const [fieldValue, setFieldValue] = useState("")
return (
<>
<Field label="选项值" isLink onClick={() => setOpen(true)}>
<Input readonly placeholder="请选择" value={fieldValue} />
</Field>
<Popup open={open} rounded placement="bottom" onClose={setOpen}>
<Popup.Close />
<Cascader
options={dynamic}
loadData={(_values_) => {
const len = _values_.length
return new Promise((resolve) => {
resolve(len > 3 ? [] : [
{ label: `动态${len}-1`, value: Math.random() },
{ label: `动态${len}-2`, value: Math.random() }
])
})
}}
title="请选择"
swipeable
value={value}
onSelect={setValue}
onChange={(_values_, options) => {
setOpen(false)
setFieldValue(
options.map(item => item.children).join("/")
)
}}
/>
</Popup>
</>
)
}
Tips: 数据量大时,可关闭 animated,swipeable,避免卡顿
const fieldNames = {
label: "name",
value: "code",
children: "data"
}
function CustomFieldCascader() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState<string[]>([])
const [fieldValue, setFieldValue] = useState("")
return (
<>
<Field label="选项值" isLink onClick={() => setOpen(true)}>
<Input readonly placeholder="请选择地区" value={fieldValue} />
</Field>
<Popup open={open} rounded placement="bottom" onClose={setOpen}>
<Popup.Close />
<Cascader
options={customArea}
fieldNames={fieldNames}
value={value}
title="请选择地区"
placeholder="请选择"
onSelect={setValue}
onChange={(_values_, options) => {
setOpen(false)
setFieldValue(
options.map(item => item.children).join("/")
)
}}
/>
</Popup>
</>
)
}
可以通过 Cascader.Header
, Cascader.Tab
, Cascader.Option
,配合 useCascader
自己控制DOM
import { Cascader, Field, Popup } from "@taroify/core"
import { ArrowRight } from "@taroify/icons"
import { useState } from "react"
import { useCascader } from "@taroify/hooks"
function BasicCascader() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState<string[]>([])
const [fieldValue, setFieldValue] = useState("")
const { columns } = useCascader({ value, depth: 3, options: area })
return (
<>
<Field label="选项值" isLink onClick={() => setOpen(true)}>
<Input readonly placeholder="请选择地区" value={fieldValue} />
</Field>
<Popup open={open} rounded placement="bottom" onClose={setOpen}>
<Popup.Close />
<Cascader
value={value}
onSelect={setValue}
onChange={(_values_, options) => {
setOpen(false)
setFieldValue(
options.map(item => item.children).join("/")
)
}}
>
<Cascader.Header>请选择所在地区</Cascader.Header>
{
columns.map((options, index) => (
<Cascader.Tab key={index}>
{
options.map(option => (
<Cascader.Option key={option.value} value={option.value}>
{option.label}
</Cascader.Option>
))
}
</Cascader.Tab>
))
}
</Cascader>
</Popup>
</>
)
}
通过改变selected.children,同样可以动态加载选项
const onSelect = (_value) => {
const level = _value.length - 1
const selected = columns[level].find(item => item.value === _value[level]);
if (selected && level < depth - 1) {
selected.children = [
{ label: `动态${level}-1`, value: Math.random() },
{ label: `动态${level}-2`, value: Math.random() }
]
}
setValue(_value)
}
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
value | 选中项的值 | string[] | - |
placeholder | 未选中时的提示文案 | ReactNode | 请选择 |
title | 顶部标题 | ReactNode | - |
swipeable | 是否开启手势左右滑动切换 | boolean | false |
animated | 是否开启动过渡动画 | boolean | true |
options | 可选项数据源 | CascaderDataOption | [] |
loadData | 动态加载数据 | (values: string[], options: CascaderEventOption[]) => Promise<any[]> | _ |
fieldNames | 自定义 options 结构中的字段 | CascaderFieldNames | { label: 'label', value: 'value', children: 'children' } |
事件 | 说明 | 回调参数 |
---|---|---|
onSelect | 选中项变化时触发 | values: any[], options: CascaderEventOption[] |
onChange | 全部选项选择完成后触发 | values: any[], options: CascaderEventOption[] |
onTabClick | 点击标签时触发 | event: Tabs.TabEvent |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
children | 选项内容(必填) | ReactNoe | - |
value | 选项对应的值(必填) | string | number | - |
disabled | 是否禁用选项 | boolean | false |
通过@taroify/core/cascader
导入类型
import type {
CascaderDataOption, CascaderEventOption, CascaderFieldNames
} from '@taroify/core/cascader'
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
名称 | 默认值 | 描述 |
---|---|---|
—cascader-active-color | var(—blue, $blue) | - |
—cascader-header-height | 48px * $hd | - |
—cascader-header-padding | 0 var(—padding-md) | - |
—cascader-header-font-size | var(—font-size-lg) | - |
—cascader-header-font-weight | var(—font-weight-bold) | - |
—cascader-header-line-height | 20px * $hd | - |
—cascader-tabs-height | 48px * $hd | - |
—cascader-tab-font-weight | var(—font-weight-bold) | - |
—cascader-tab-color | var(—text-color) | - |
—cascader-inactive-tab-color | var(—gray-6) | - |
—cascader-options-height | 384px * $hd | - |
—cascader-option-padding | 10px * $hd var(—padding-md) | - |
—cascader-option-font-size | var(—font-size-md) | - |
—cascader-option-line-height | var(—line-height-md) | - |
—cascader-option-active-background-color | var(—active-color) | - |
—cascader-disabled-option-color | var(—gray-5) | - |
—cascader-active-option-color | var(—cascader-active-color) | - |
—cascader-active-option-font-weight | var(—font-weight-bold) | - |
—cascader-active-icon-font-size | 18px * $hd | - |