ant-design-vue Cascader 级联选择组件完全指南:API、搜索、多选与动态加载实战
2026/9/20 2:17:40 网站建设 项目流程
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-vue

🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-vue
点击查看免费下载

级联选择框(Cascader)是 ant-design-vue 中用于处理"多级关联数据"选择的核心组件,常用于省市区、组织层级、商品分类等具有父子层级关系的场景。本文将基于 components/cascader/index.en-US.md 官方文档,结合 components/cascader/index.tsx 源码实现与 components/cascader/demo 目录下的 14 个真实示例,系统讲解 Cascader 的全部配置项、事件、方法与高级用法,帮助你快速掌握该组件的完整能力。

When To Use:什么场景适合使用级联选择

官方文档给出了三个典型的适用场景:

  • 需要从一组相互关联的数据集中进行选择,例如省/市/区、公司层级、事物分类等树状结构数据;
  • 数据量大且具有多级分类,通过逐级分类拆分,降低单次选择的复杂度;
  • 希望在一个浮层中完成级联选择,提供更好的用户体验。

简单来说,只要你的选择数据天然存在父子层级关系(如 components/cascader/demo/basic.vue 中的"省份 → 城市 → 景区"数据),级联选择框就是比普通下拉框更合适的交互方案。

基础用法:最简可运行的 Cascader

官方文档开篇给出了最基础的使用示例:

<a-cascader :options="options" v-model:value="value" />

对应 components/cascader/demo/basic.vue 中的完整实现:

<template> <a-cascader v-model:value="value" :options="options" placeholder="Please select" /> </template> <script lang="ts" setup> import { ref } from 'vue'; import type { CascaderProps } from 'ant-design-vue'; const options: CascaderProps['options'] = [ { value: 'zhejiang', label: 'Zhejiang', children: [ { value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake' }], }, ], }, { value: 'jiangsu', label: 'Jiangsu', children: [ { value: 'nanjing', label: 'Nanjing', children: [{ value: 'zhonghuamen', label: 'Zhong Hua Men' }], }, ], }, ]; const value = ref<string[]>([]); </script>

需要注意两个关键点:

  1. options是树形嵌套结构,每个节点可包含valuelabelchildren
  2. value是路径数组(如['zhejiang', 'hangzhou', 'xihu']),v-model:value双向绑定选中路径,而非单个叶子值。

组件底层基于vc-cascader实现(见 components/vc-cascader 目录),外层 components/cascader/index.tsx 负责与 ant-design-vue 的主题、表单、尺寸体系对接,并将内部 Select 的视觉样式复用到 Cascader 上。

API 总览:完整参数表

以下参数表完整继承自官方文档,并补充了参数的作用说明。默认引入方式为全局注册后的<a-cascader>标签。

PropertyDescriptionTypeDefaultVersion
allowClear是否允许清除booleantrue
autofocus组件挂载时是否自动获取焦点booleanfalse
bordered是否有边框样式booleantrue3.2
clearIcon自定义清除图标slot-3.2
changeOnSelect(单选时生效)设为 true 后,每次选中都触发 change,允许只选父级booleanfalse
disabled是否禁用选择booleanfalse
displayRender展示已选项的渲染函数,可使用#displayRender="{labels, selectedOptions}"({labels, selectedOptions}) => VNodelabels => labels.join(' / ')
popupClassName弹出浮层额外的 classNamestring-4.0
dropdownStyle弹出浮层额外的样式CSSProperties{}3.0
expandIcon自定义当前项展开图标slot-3.0
expandTrigger展开当前项的方式:点击或悬停click|hover'click'
fieldNames自定义 label、value、children 的字段名object{ label: 'label', value: 'value', children: 'children' }
getPopupContainer选择器浮层渲染到的父节点,默认渲染到body。出现定位问题时,可改为可滚动内容并设置相对定位Function(triggerNode)() => document.body
loadData动态加载选项,注意不能与showSearch同时使用(selectedOptions) => void-
maxTagCount最多显示的 tag 数量,responsive模式会消耗渲染性能number |responsive-3.0
maxTagPlaceholder未展示 tag 的占位内容v-slot | function(omittedValues)-3.0
multiple是否支持多选boolean-3.0
notFoundContent无匹配结果时展示的内容string | slot'Not Found'
open控制级联浮层的显隐boolean-3.0
options级联数据源Option[]-
placeholder输入框占位符string'Please select'
placement使用内置浮层对齐配置bottomLeft|bottomRight|topLeft|topRightbottomLeft3.0
removeIcon自定义移除图标slot-3.2
searchValue设置搜索值,需配合showSearch使用string-3.0
showSearch单选模式下是否显示搜索框boolean | objectfalse
size输入框尺寸large|default|smalldefault
status校验状态'error' | 'warning'-3.3.0
suffixIcon自定义后缀图标string | VNode | slot-
showCheckedStrategy多选时选中项的展示方式:Cascader.SHOW_CHILD只显示子节点;Cascader.SHOW_PARENT仅当父节点下所有子节点都被选中时才显示父节点Cascader.SHOW_PARENT|Cascader.SHOW_CHILDCascader.SHOW_PARENT3.3.0
tagRendermultiple模式下自定义 tag 渲染slot-3.0
value(v-model)选中的值string[] | number[]-

与 Select 体系的继承关系

从源码看,components/cascader/index.tsx 中的cascaderProps()通过...omit(vcCascaderProps(), ['customSlots', 'checkable', 'options'])继承了vc-cascader的全部属性,仅排除掉内部使用的customSlotscheckableoptions,再补充声明multiplesizeborderedplacementsuffixIconstatuspopupClassName以及已废弃的dropdownClassName等属性。同时组件在setup中调用useConfigInject('cascader', props)注入 ConfigProvider 配置,并使用useSelectStyleuseStyle分别应用 Select 与 Cascader 的样式(components/cascader/style/index.ts),因此它在外观、尺寸、状态上与 Select 保持完全一致的设计语言。

注意:dropdownClassName已被标记为@deprecated,源码会在非生产环境通过devWarning提示改用popupClassName(见 components/cascader/index.tsx)。

数据源 Option:结构、字段与叶子节点

官方文档定义的Option接口如下:

interface Option { value: string | number; label?: VNode; disabled?: boolean; children?: Option[]; // 指定该节点是否为叶子节点(当设置了 `loadData` 时生效)。 // `false` 会强制将该树节点视为父节点。 // 即使当前节点没有 children,也会显示展开图标。 isLeaf?: boolean; }

各字段含义:

  • value:必填,节点值,最终会以路径数组形式出现在v-model:value中;
  • label:节点展示文案,也支持 VNode 以便渲染复杂内容;
  • disabled:禁用该节点(参考 components/cascader/demo/disabled-option.vue);
  • children:子节点数组,形成级联层级;
  • isLeaf:与loadData配合使用。当某节点isLeaf: false且无 children 时,会展示展开图标并触发加载回调;默认情况下无 children 的节点会被视为叶子节点。

自定义字段名 fieldNames

当后端返回的数据字段不叫label/value/children时,可通过fieldNames重映射,如 components/cascader/demo/fields-name.vue 所示:

<a-cascader v-model:value="value" :field-names="{ label: 'name', value: 'code', children: 'items' }" :options="options" placeholder="Please select" />

此时数据需写成:

const options = [ { code: 'zhejiang', name: 'Zhejiang', items: [ { code: 'hangzhou', name: 'Hangzhou', items: [{ code: 'xihu', name: 'West Lake' }] }, ], }, ];

changeOnSelect:允许只选父级

默认情况下,Cascader 要求必须选中叶子节点才触发 change。当希望"选择到某一级就立即提交"(例如只选到省份)时,开启changeOnSelect即可,见 components/cascader/demo/change-on-select.vue:

<a-cascader v-model:value="value" :options="options" placeholder="Please select" change-on-select />

官方文档特别注明:该属性仅对单选模式生效。

expandTrigger 与 expandIcon:展开交互与图标定制

移入展开

通过expand-trigger="hover"可改为鼠标移入即展开下级菜单、点击完成选择,见 components/cascader/demo/hover.vue:

<a-cascader v-model:value="value" :options="options" expand-trigger="hover" placeholder="Please select" />

默认值为'click',即点击展开。

自定义展开图标

expandIcon是一个 slot,可完全替换默认的展开箭头。从源码看,未提供该 slot 时组件会根据direction(RTL 与否)自动选择RightOutlinedLeftOutlined作为展开图标(components/cascader/index.tsx),并在节点处于加载态时渲染带spinLoadingOutlined加载图标。

搜索 showSearch:在级联中直接搜选项

单选模式下通过showSearch开启搜索。官方文档的用法示例为:

<a-cascader v-model:value="value" :options="options" :show-search="{ filter }" placeholder="Please select" />

对应的自定义filter函数(见 components/cascader/demo/search.vue):

import type { ShowSearchType } from 'ant-design-vue/es/cascader'; const filter: ShowSearchType['filter'] = (inputValue, path) => { return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1); };

filter接收(inputValue, path)两个参数,path是从根到当前节点的完整路径数组,返回true表示该选项进入过滤结果集。上面的实现表示"路径上任一节点的 label 包含输入值即命中"。

showSearch 对象配置项

showSearch传对象时,支持以下字段:

PropertyDescriptionTypeDefault
filter过滤函数,接收 inputValue 和 path,返回 true 则包含该选项,否则排除function(inputValue, path): boolean
limit过滤结果的数量上限number | false50
matchInputWidth结果列表宽度是否等于输入框宽度boolean
render渲染过滤结果,可使用#showSearchRender="{inputValue, path}"function({inputValue, path}): VNode
sort对过滤结果排序function(a, b, inputValue)

从源码看(components/cascader/index.tsx),当showSearch为真值时,组件会将其与内置的defaultSearchRender合并:默认渲染逻辑会对命中的关键词做高亮(用-menu-item-keyword样式包裹匹配片段,见 components/cascader/index.tsx),并将路径各级 label 用/连接展示。

注意:showSearch暂不支持服务端搜索(官方 demo 中引用了 ant-design/ant-design 的 issue #5547 说明此限制),搜索在客户端完成;同时官方文档强调loadDatashowSearch无法一起使用。

多选 multiple:批量选择与展示策略

multiple模式自 3.0 起支持,见 components/cascader/demo/multiple.vue:

<h4>Cascader.SHOW_PARENT</h4> <a-cascader v-model:value="value" style="width: 100%" multiple max-tag-count="responsive" :options="options" placeholder="Please select" /> <h4>Cascader.SHOW_CHILD</h4> <a-cascader v-model:value="value" style="width: 100%" multiple max-tag-count="responsive" :options="options" placeholder="Please select" :show-checked-strategy="Cascader.SHOW_CHILD" />

多选模式下需要理解两个核心概念:

  1. showCheckedStrategy:控制已选项的展示方式。默认Cascader.SHOW_PARENT——当父节点下所有子节点都被选中时,只展示父节点;Cascader.SHOW_CHILD则始终展示叶子节点。这两个常量通过Cascader.SHOW_PARENT/Cascader.SHOW_CHILD静态属性访问,在源码中由Object.assign(Cascader, { SHOW_CHILD, SHOW_PARENT })挂载(components/cascader/index.tsx),底层实现在 components/vc-cascader 中。
  2. maxTagCount:限制 tag 展示数量,responsive会根据宽度自适应折叠。

与多选相关的补充说明:

  • displayRendermultiple模式下不生效,源码会在非生产环境抛出警告,提示改用tagRender(components/cascader/index.tsx);
  • tagRenderslot 可自定义每个已选项 tag 的内容与样式,如 components/cascader/demo/tagRender.vue 中将其渲染为蓝色<a-tag>
<a-cascader v-model:value="value" multiple :options="options" placeholder="Please select"> <template #tagRender="data"> <a-tag :key="data.value" color="blue">{{ data.label }}</a-tag> </template> </a-cascader>

loadData:大数据量下的动态加载

当级联数据量很大、子节点需要按需请求时,使用loadData懒加载子选项。参考 components/cascader/demo/lazy.vue:

<a-cascader v-model:value="value" :options="options" :load-data="loadData" placeholder="Please select" change-on-select />
const options = ref<CascaderProps['options']>([ { value: 'zhejiang', label: 'Zhejiang', isLeaf: false }, { value: 'jiangsu', label: 'Jiangsu', isLeaf: false }, ]); const loadData: CascaderProps['loadData'] = selectedOptions => { const targetOption = selectedOptions[selectedOptions.length - 1]; targetOption.loading = true; // 模拟异步请求子选项 setTimeout(() => { targetOption.loading = false; targetOption.children = [ { label: `${targetOption.label} Dynamic 1`, value: 'dynamic1' }, { label: `${targetOption.label} Dynamic 2`, value: 'dynamic2' }, ]; options.value = [...options.value]; }, 1000); };

使用要点:

  • 顶层选项需要设置isLeaf: false,否则组件会把无 children 的节点当作叶子节点,不触发加载;
  • 加载过程中给节点设置loading = true,组件会展示旋转加载图标;
  • 加载完成后将children写入目标节点,并用展开运算符创建新数组触发响应式更新
  • 官方文档明确:loadData不能showSearch同时使用。

自定义渲染:displayRender 与自定义触发器

自定义已选项展示

displayRender接收{ labels, selectedOptions },可用于在输入框内定制已选项的展示,例如 components/cascader/demo/custom-render.vue 为最后一项附加可点击的邮编链接:

<a-cascader v-model:value="value" placeholder="Please select" :options="options" style="width: 100%"> <template #displayRender="{ labels, selectedOptions }"> <span v-for="(label, index) in labels" :key="selectedOptions[index].value"> <span v-if="index === labels.length - 1"> {{ label }} ( <a @click="e => handleAreaClick(e, label, selectedOptions[index])"> {{ selectedOptions[index].code }} </a> ) </span> <span v-else>{{ label }} /</span> </span> </template> </a-cascader>

默认展示为各级 label 用/连接(默认值labels => labels.join(' / '))。源码将displayRender同时兼容函数与 slot 两种传法:displayRender={props.displayRender || slots.displayRender}(components/cascader/index.tsx)。

自定义触发器

Cascader 选择框默认是一个带前缀图标的下拉触发区域,可通过 slot 完全替换触发 UI,实现"自定义触发器"(参考 components/cascader/demo/custom-trigger.vue),适合把级联面板嵌入按钮、文本等任意交互元素中。

事件、v-model 与实例方法

事件

Events NameDescriptionArgumentsversion
change完成级联选择时触发(value, selectedOptions) => void-
dropdownVisibleChange浮层显示/隐藏时触发(value) => void-3.0
search输入值变化时触发(value) => void-1.5.4

其中change事件在源码中通过handleChange转发:依次触发update:value(驱动v-model:value)、change,并调用表单上下文的onFieldChange通知 FormItem 校验(components/cascader/index.tsx),因此组件在 Form 中能自动参与校验与字段状态同步。

实例方法

NameDescription
blur()移除焦点
focus()获取焦点

组件通过expose({ focus, blur })暴露这两个方法(components/cascader/index.tsx),可配合模板 ref 调用,例如<a-cascader ref="cascaderRef" />后执行cascaderRef.value?.focus()。测试文件 components/cascader/tests/index.test.js 中通过共享的focusTest工具验证了焦点行为的正确性。

外观与状态:尺寸、边框、校验与浮层

  • sizelarge/default/small三档尺寸,源码会为largesmall分别添加-lg-sm修饰类(components/cascader/index.tsx),并优先读取 ConfigProvider 与 Space Compact 注入的尺寸;
  • bordered:3.2 起支持,设为false得到无边框样式,对应类名-borderless
  • status:3.3.0 起支持error/warning校验状态,源码通过getMergedStatus合并 FormItem 上下文状态与自身状态,并应用getStatusClassNames生成状态类名(components/cascader/index.tsx),在 Form 中可自动继承校验状态;
  • placementbottomLeft/bottomRight/topLeft/topRight,默认bottomLeft;在 RTL 环境下默认自动切换为bottomRight(components/cascader/index.tsx);
  • popupClassName / dropdownStyle:分别设置浮层的额外类名与内联样式,用于浮层定制;
  • getPopupContainer:浮层默认渲染到document.body,当父容器发生滚动或定位(如overflow: hidden)导致浮层位置异常时,可传入函数将其渲染到可滚动容器内;
  • allowClear / clearIcon / removeIcon / suffixIcon:清除能力与图标定制,图标相关处理复用 Select 的getIcons工具(components/cascader/index.tsx),且clearIconremoveIcon均支持 slot 形式(3.2 起);
  • notFoundContent:无匹配结果时显示的内容,默认'Not Found',源码中未提供时会回退到 ConfigProvider 的renderEmpty('Cascader')空状态(components/cascader/index.tsx)。

源码架构小结

从整体架构看,Cascader 采用"外层组件 + vc-cascader 内核"的分层设计:

  • components/vc-cascader 是组件内核,包含Cascader.tsx主文件、OptionList面板渲染、useSearchConfig/useSearchOptions搜索逻辑、useEntities节点实体管理、useDisplayValues已选项展示值计算等 hooks,以及commonUtil/treeUtil树工具;
  • components/cascader/index.tsx 是面向用户的外层封装,负责:合并 vc 属性并补充 Vue 化声明、注入 ConfigProvider / Form / DisabledContext 上下文、计算前缀类名与 SSR 样式、组装展开/清除/后缀/加载图标、转发事件并暴露 focus/blur 方法;
  • components/cascader/demo 提供 14 个覆盖基本用法、搜索、多选、懒加载、字段映射、hover、自定义渲染、tag 定制等场景的完整示例;
  • components/cascader/tests/index.test.js 覆盖面板显隐、搜索过滤、焦点行为等核心逻辑,是验证组件行为可靠性的直接依据。

总结

ant-design-vue 的 Cascader 组件以"路径数组"作为数据模型,通过丰富的配置项覆盖了从最基础的省市区选择到多选、搜索、懒加载、自定义渲染等全部实际场景。掌握options树结构、fieldNames字段映射、changeOnSelect父级选择、showCheckedStrategy多选展示策略、loadData动态加载与showSearch搜索配置这六个核心能力,即可在项目中游刃有余地处理一切层级关联数据的选择需求。

  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-vue

🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-vue
点击查看免费下载

相关推荐

上一篇:从乱码到完美:OCRmyPDF自定义字体全攻略
下一篇:Sniffnet网络协议解析:HTTP/HTTPS流量识别方法

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询