Cascader
级联选择器,点击(或 hover)逐级展开列,单选叶子/任一层级;支持 multiple 多选(每列 checkbox + 父子联动 + 多 tag 回显)、可搜索过滤(本地/远程 + 结果虚拟滚动)、动态加载子节点、自定义字段映射与触发器/结果渲染。
如何引入
import { Cascader } from '@chenzy-design/svelte';基础用法
逐级展开树形数据,支持搜索过滤与清空
多选
multiple 开启每列复选框与父子联动,maxTagCount 折叠溢出标签
默认值与任意级选择
defaultValue 设置初始路径,changeOnSelect 允许选中任意层级
禁用选项
通过节点 disabled 字段禁用单个选项或整棵子树
动态加载
loadData 在点击非叶子节点时异步拉取子级,加载中显示 spinner
数量上限与内嵌标签
max 限制多选可勾选数量,超出触发 onExceed 且不选入;insetLabel 在触发器值前内嵌标签
可搜索多选
multiple + filterable 搜索并多选,filterSorter 对搜索结果自定义排序
自定义搜索结果
filterRender 自定义搜索命中项的整行渲染
严格禁用
disableStrictly 开启后,禁用节点不随父/子联动改变选中态
节点选中关系
checkRelation="unRelated" 使节点选中互不影响,可任意层级独立勾选
仅叶子节点
leafOnly 使 value 只包含叶子节点,不折叠为父路径
自定义显示
separator 自定义路径分隔符,displayRender 自定义触发器回填格式
悬停展开与点击选中
showNext="hover" 悬停展开子列,clickToSelect 点击任意节点即选中
顶部/底部附加项
topSlot / bottomSlot 在下拉面板顶部、底部渲染固定附加内容
自定义触发器
triggerRender 完全自定义选择框的触发器外观
远程搜索
remote 关闭本地过滤,onSearch 回调里异步更新 treeData
自定义字段映射
keyMaps 将 label/value/children 映射到数据中的自定义字段名
回调返回对象
onChangeWithObject 使 onChange 入参从 value 变为完整节点对象
受控
外部持有 value 配合 onChange 双向同步,可编程式设置选中路径
API 参考
Cascader
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
value | 单选单条路径;多选多条路径 | (string|number)[] | (string|number)[][] | undefined |
defaultValue | — | (string|number)[] | (string|number)[][] | undefined |
treeData | — | CascaderNode[] | [] |
open | — | boolean | undefined |
defaultOpen | — | boolean | false |
multiple | 每列 checkbox 多选 + 父子联动,多 tag 回显 | boolean | false |
size | — | 'small'|'default'|'large' | default |
status | — | 'default'|'warning'|'error' | default |
placeholder | — | string | '请选择' |
disabled | — | boolean | false |
clearable | — | boolean | false |
changeOnSelect | 单选:点击任一层级(含中间非叶子)即提交该路径并触发 onChange,非叶子同时展开子列且不关闭面板,叶子提交并关闭;关闭时仅叶子提交并关闭 | boolean | false |
expandTrigger | 'hover' 悬停非叶子节点即展开子级列 | 'click'|'hover' | 'click' |
leafOnly | 多选时完全勾选的父级折叠为父路径(只回传/计数到该父级);默认 false 仅回传叶子 | boolean | false |
filterable | 可搜索(向后兼容别名,等价 filterTreeNode=true) | boolean | false |
filterTreeNode | 是否可搜索及自定义匹配:false 关闭;true 默认 label 链子串匹配;函数自定义谓词。未传时回退 filterable | boolean | ((query, path) => boolean) | undefined |
filterLeafOnly | 搜索结果是否仅展示到叶子路径 | boolean | true |
displayProp | 触发器回显使用的字段 | 'label'|'value' | 'label' |
separator | 路径分隔符(回显 + 搜索 label 链拼接) | string | ' / ' |
maxTagCount | 多选 Tag 溢出折叠阈值:超出显示前 N 个 + +M | number | undefined |
emptyContent | 列为空时内容;缺省走 i18n | string | Snippet | undefined |
destroyOnClose | 关闭即卸载浮层内容({#if}),重开重建;默认 false 首开后保留 DOM 仅隐藏 | boolean | false |
zIndex | 浮层层级 | number | 1030 |
getPopupContainer | 浮层挂载容器,缺省 document.body;非 body 容器时 absolute 定位相对该容器 | () => HTMLElement | null | undefined | undefined |
columnWidth | 列宽:统一(number)或逐列(number[],超出取末项) | number | number[] | 180 |
loadData | 动态加载子节点 | (node: CascaderNode) => Promise<CascaderNode[]> | undefined |
displayRender | 自定义触发器选中路径回显(单选 + 多选每个 tag 共用) | (labels: string[], selectedNodes: CascaderNode[]) => string | undefined |
onChange | 单选回调单条路径;多选回调多条叶子路径 | (value: (string|number)[] | (string|number)[][]) => void | undefined |
onOpenChange | — | (open: boolean) => void | undefined |
ariaLabel | — | string | undefined |
borderless | 无边框模式 | boolean | false |
prefix | 前置内容 | Snippet | string | undefined |
insetLabel | 内嵌标签:触发器在值前渲染的标签(如「地区:」),Semi 中为 prefix 的别名 | Snippet | string | undefined |
insetLabelId | 内嵌标签的 DOM id(供外部 aria-labelledby 引用) | string | undefined |
suffix | 后置内容 | Snippet | string | undefined |
clearIcon | 自定义清除图标 | Snippet | undefined |
expandIcon | 自定义展开图标(expandIcon / arrowIcon 均可,expandIcon 优先) | Snippet | undefined |
arrowIcon | 自定义右侧下拉箭头(expandIcon 的别名) | Snippet | undefined |
motion | 下拉框展开动画 | boolean | true |
mouseEnterDelay | 鼠标移入延迟(ms) | number | 50 |
mouseLeaveDelay | 鼠标移出延迟(ms) | number | 50 |
autoAdjustOverflow | 下拉框自动调整方向 | boolean | true |
position | 下拉框方向 | string | 'bottomStart' |
style | 选择框样式 | string | undefined |
dropdownStyle | 下拉菜单样式(合并进浮层根节点,不覆盖内置定位样式) | string | Record<string, string> | undefined |
dropdownClassName | 追加到浮层根节点的自定义类名(与内置类名并存) | string | undefined |
dropdownMargin | 浮层与 trigger 的额外间距(px);数字映射到浮层 offset,对象取 marginTop | number | { marginTop?: number; marginBottom?: number; marginLeft?: number; marginRight?: number } | undefined |
onBlur | 失焦回调 | (e: MouseEvent) => void | undefined |
onFocus | 聚焦回调 | (e: MouseEvent) => void | undefined |
preventScroll | 聚焦时阻止滚动 | boolean | false |
stopPropagation | 阻止下拉框点击冒泡 | boolean | true |
topSlot | 面板顶部插槽 | Snippet | undefined |
bottomSlot | 面板底部插槽 | Snippet | undefined |
searchPosition | 搜索框位置:'trigger' 内置;'custom' 不渲染内置搜索框 | 'trigger'|'custom' | 'trigger' |
searchPlaceholder | 搜索框占位文字 | string | undefined |
treeNodeFilterProp | 搜索时过滤的属性 | string | 'label' |
filterRender | 自定义搜索结果项渲染 | Snippet<[{ path: FlatPath }]> | undefined |
filterSorter | 搜索结果自定义排序 | (a: FlatPath, b: FlatPath, input: string) => number | undefined |
onSearch | 搜索输入回调 | (value: string) => void | undefined |
remote | 远程搜索模式:跳过本地过滤,只触发 onSearch | boolean | false |
virtualizeInSearch | 搜索结果虚拟滚动配置 | { height: number; width: number; itemSize: number } | undefined |
autoMergeValue | 选中父节点时 value 不包含后代 | boolean | true |
checkRelation | 勾选关系:'related' 父子联动;'unRelated' 独立 | 'related'|'unRelated' | 'related' |
onChangeWithObject | onChange 回调是否返回完整 option 对象 | boolean | false |
max | 多选可勾选数量上限;超出时不选入并触发 onExceed(减少始终允许) | number | undefined |
onExceed | 超出 max 时回调,传当前(含超出项)勾选的节点集合 | (items: CascaderNode[]) => void | undefined |
showRestTagsPopover | 超出 maxTagCount 折叠的 tag 以 Popover 悬浮展示剩余项(hover +N) | boolean | false |
restTagsPopoverProps | 传给剩余 tags Popover 的额外 props(透传,可覆盖默认) | Record<string, unknown> | undefined |
showClear | 是否显示清除按钮(clearable 的别名) | boolean | undefined |
keyMaps | 自定义字段名映射 | { value?: string; label?: string; children?: string; disabled?: string; isLeaf?: string } | undefined |
clickToSelect | 点击任意节点即选中(含非叶子) | boolean | false |
enableLeafClick | 多选模式下点击叶子节点触发勾选 | boolean | false |
disableStrictly | 禁用不从父节点继承(严格禁用) | boolean | false |
showNext | 展开触发方式(canonical prop,优先于 expandTrigger) | 'click'|'hover' | 'click' |
onClear | 清空回调 | () => void | undefined |
onLoad | 异步加载完成回调 | (loadedKeys: Key[], data: CascaderNode) => void | undefined |
onSelect | 节点选中回调(单选叶子选中时) | (value: Key) => void | undefined |
onDropdownVisibleChange | 下拉面板显隐回调 | (visible: boolean) => void | undefined |
onListScroll | 列滚动回调 | (e: Event, info: { panelIndex: number; activeNode: CascaderNode | null }) => void | undefined |
triggerRender | 完全自定义触发器渲染 | Snippet<[{ value: Key[] | Key[][] | undefined; placeholder: string; isOpen: boolean; disabled: boolean }]> | undefined |
class | 根节点自定义类名(对齐 Semi className) | string | '' |
Accessibility
| ARIA role | combobox |
- combobox + 每列 listbox + option ARIA 模式
- 触发器 aria-haspopup="listbox"、aria-expanded
- 每列 option aria-selected 标记当前路径
- disabled 节点 aria-disabled 且不可点击
设计变量
| 变量 | 默认值 | 用法 |
|---|---|---|
--cd-cascader-column-border | var(--cd-color-fill-0) | 级联选择各级菜单分割线颜色(组件消费) |
--cd-color-cascader-icon-default | var(--cd-color-text-2) | 级联选择触发器图标颜色 - 默认 |
--cd-color-cascader-label-text-default | var(--cd-color-text-2) | 级联选择 prefix 文字颜色 |
--cd-color-cascader-option-bg-active | var(--cd-color-fill-1) | 级联选择菜单项背景颜色 - 按下 |
--cd-color-cascader-option-bg-hover | var(--cd-color-fill-0) | 级联选择菜单项背景颜色 - 悬浮 |
--cd-color-cascader-option-icon-default | var(--cd-color-cascader-icon-default) | 级联选择菜单项图标颜色 |
--cd-color-cascader-option-main-text-default | var(--cd-color-text-0) | 级联选择菜单项文字颜色 |
--cd-color-cascader-prefix-suffix-text-default | var(--cd-color-text-2) | 级联选择前后缀文字颜色 |
--cd-color-cascader-select-highlight | var(--cd-color-primary) | 级联选择器搜索命中后文字高亮的颜色 |