Skip to content

Cascader 级联选择 - Vant 4

Cascader 级联选择

🔗 介绍

想象一下,你正在网购时需要选择收货地址 📍,从省份到城市再到区县,一层层地精准定位。Cascader 级联选择组件就像一个智能的"地图导航员" 🗺️,帮你在复杂的层级数据中轻松穿梭!

无论是省市区三级联动、商品分类筛选,还是组织架构选择,Cascader 都能让原本繁琐的多层选择变得如丝般顺滑 ✨。它就像一个贴心的向导,一步步引导用户找到最终目标,让复杂的数据结构在指尖变得简单易懂!

📦 引入

通过以下方式来全局注册组件,更多注册方式请参考组件注册

js
import { createApp } from'vue'; 
import { Cascader } from'vant'; 
const app = createApp(); 
app.use(Cascader);

🎯 代码演示

基础用法

就像搭积木一样简单 🧱!Cascader 与 Field 和 Popup 组件完美配合,就像三个好朋友手拉手,共同打造出丝滑的选择体验。

点击输入框,弹出层级选择面板,一层层选择下去,最终的路径会自动拼接成完整的选择结果 🎯。这种体验就像在玩一个有趣的"寻宝游戏",每一步都充满期待!

html
js
import { ref } from'vue'; 
export default { 
    setup() {
        const show = ref(false); 
        const fieldValue = ref(''); 
        const cascaderValue = ref(''); 
        // 选项列表,children 代表子选项,支持多级嵌套
        const options = [ { text: '浙江省', value: '330000', children: [{ text: '杭州市', value: '330100' }], }, { text: '江苏省', value: '320000', children: [{ text: '南京市', value: '320100' }], }, ]; 
        // 全部选项选择完毕后,会触发 finish 事件
        const onFinish = ({ selectedOptions }) => { 
            show.value = false; 
            fieldValue.value = selectedOptions.map((option) => option.text).join('/'); 
        }; 
            return { show, options, onFinish, fieldValue, cascaderValue, }; 
        }
};

中国省市区数据

做电商应用最头疼的是什么?当然是省市区数据啦 😅!别担心,Vant 就像一个贴心的管家,已经为你准备好了一份完整的中国省市区数据 🇨🇳。

这份数据就像一个"地理百科全书",从黑龙江到海南,从新疆到上海,应有尽有!只需要安装一个小小的 npm 包,就能让你的应用瞬间拥有全国地址选择能力 🚀:

bash

# 通过 npm 
npm i @vant/area-data 
# 通过 yarn 
yarn add @vant/area-data 
# 通过 pnpm p
npm add @vant/area-data 
# 通过 Bun 
bun add @vant/area-data
html
js
import { ref } from'vue'; 
import { useCascaderAreaData } from'@vant/area-data'; 
export default { setup() { 
    const show = ref(false); 
    const fieldValue = ref(''); 
    const cascaderValue = ref(''); 
    const options = useCascaderAreaData(); 
    const onFinish = ({ selectedOptions }) => { show.value = false; fieldValue.value = selectedOptions.map((option) => option.text).join('/'); }; 
    return { show, options, onFinish, fieldValue, cascaderValue, }; 
}, 
};

Tips: 中国的行政区划每年都会有变动,如果发现省市区数据未及时更新,欢迎提 Pull Request 帮助我们更新。你可以在「国家统计局 - 全国区划代码」「民政部 - 行政区划代码」上查询到最新数据,请根据官方数据进行核实。

自定义颜色

想要让你的级联选择器更有个性?🎨 active-color 属性就像一支神奇的画笔,可以为选中状态涂上你喜欢的颜色!

无论是品牌蓝、活力橙还是优雅紫,都能让你的组件与众不同,完美融入应用的整体设计风格 ✨。

html

异步加载选项

有时候数据太多,一次性加载会让用户等得花儿都谢了 🌸。这时候异步加载就像一个"智能快递员" 📦,按需配送,用户选到哪一层,就加载哪一层的数据。

通过监听 change 事件,你可以在用户选择时动态获取下级数据,让选择过程既流畅又高效!

html
js
import { ref } from'vue'; 
import { closeToast, showLoadingToast } from'vant'; 
export default { setup() { 
    const show = ref(false); 
    const fieldValue = ref(''); 
    const cascaderValue = ref(''); 
    const options = ref([ { text: '浙江省', value: '330000', children: [], }, ]); 
    const onChange = ({ value }) => { 
        if ( value === options.value[0].value && options.value[0].children.length === 0 ) {
            // 模拟数据请求
            showLoadingToast('加载中...'); 
            setTimeout(() => { 
                options.value[0].children = [ { text: '杭州市', value: '330100' }, { text: '宁波市', value: '330200' }, ]; 
                closeToast(); }, 1000); 
        } 
     }; 
     const onFinish = ({ selectedOptions }) => { show.value = false; fieldValue.value = selectedOptions.map((option) => option.text).join('/'); }; 
     return { show, options, onFinish, fieldValue, cascaderValue, }; 
     }, 
};

自定义字段名

每个项目都有自己的"语言习惯" 🗣️,有的喜欢用 name,有的偏爱 title,有的钟情于 label。Cascader 就像一个"翻译官" 🌐,通过 field-names 属性让你的数据结构和组件完美对接!

不管你的后端同事用什么字段名,Cascader 都能轻松适配,让数据对接变得毫无压力 💪。

html
js
import { ref } from'vue'; exportdefault { setup() { const code = ref(''); const fieldNames = { text: 'name', value: 'code', children: 'items', }; const options = [ { name: '浙江省', code: '330000', items: [{ name: '杭州市', code: '330100' }], }, { name: '江苏省', code: '320000', items: [{ name: '南京市', code: '320100' }], }, ]; return { code, options, fieldNames, }; }, };

自定义选项上方内容

想要在选项列表上方加点"调料" 🧂?比如一个搜索框、一段提示文字,或者一个可爱的小图标?

通过插槽的魔法,你可以在每一层选项的上方添加任何你想要的内容,让选择体验更加丰富多彩 🌈!

html
js
import { ref } from'vue'; exportdefault { setup() { const code = ref(''); const options = [ { name: '浙江省', code: '330000', items: [{ name: '杭州市', code: '330100' }], }, { name: '江苏省', code: '320000', items: [{ name: '南京市', code: '320100' }], }, ]; return { code, options, }; }, };

API

Props

参数说明类型默认值
v-model选中项的值*stringnumber*
title顶部标题string-
options可选项数据源CascaderOption[][]
placeholder未选中时的提示文案string请选择
active-color选中状态的高亮颜色string#1989fa

| swipeable | 是否开启手势左右滑动切换 | boolean | true | | closeable | 是否显示关闭图标 | boolean | true | | show-header | 是否展示标题栏 | boolean | true | | close-icon | 关闭图标名称或图片链接,等同于 Icon 组件的 name 属性 | string | cross |

| field-names | 自定义 options 结构中的字段 | CascaderFieldNames | { text: 'text', value: 'value', children: 'children' } |

CascaderOption 数据结构

options 属性是一个由对象构成的数组,数组中的每个对象配置一个可选项,对象可以包含以下值:

键名说明类型
text选项文字(必填)string
value选项对应的值(必填)*string
color选项文字颜色string
children子选项列表CascaderOption[]
disabled是否禁用选项boolean
className为对应列添加额外的 class*string

Events

事件说明回调参数
change选中项变化时触发*{ value: string
finish全部选项选择完成后触发*{ value: string
close点击关闭图标时触发-
click-tab点击标签时触发tabIndex: number, title: string

Slots

名称说明参数
title自定义顶部标题-
option自定义选项文字{ option: CascaderOption, selected: boolean }
options-top自定义选项上方的内容{ tabIndex: number }
options-bottom自定义选项下方的内容{ tabIndex: number }

类型定义

组件导出以下类型定义:

ts
importtype { CascaderProps, CascaderOption, CascaderFieldNames } from'vant';

主题定制

样式变量

组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件

名称默认值描述
--van-cascader-header-height48px-
--van-cascader-header-padding0 var(--van-padding-md)-
--van-cascader-title-font-sizevar(--van-font-size-lg)-
--van-cascader-title-line-height20px-
--van-cascader-close-icon-size22px-
--van-cascader-close-icon-colorvar(--van-gray-5)-
--van-cascader-selected-icon-size18px-
--van-cascader-tabs-height48px-
--van-cascader-active-colorvar(--van-danger-color)-
--van-cascader-options-height384px-
--van-cascader-option-disabled-colorvar(--van-text-color-3)-
--van-cascader-tab-colorvar(--van-text-color)-
--van-cascader-unselected-tab-colorvar(--van-text-color-2)-

🎯 最佳实践

💡 使用场景推荐

Cascader 就像一个万能的"分类大师",在各种场景下都能发挥重要作用:

🏠 地址选择

html
<!-- 经典的省市区三级联动 -->
<van-cascader
  v-model="addressCode"
  title="选择地址"
  :options="areaOptions"
  @finish="onAddressFinish"
/>

🏢 组织架构选择

html
<!-- 公司部门层级选择 -->
<van-cascader
  v-model="departmentId"
  title="选择部门"
  :options="departmentOptions"
  placeholder="请选择所属部门"
/>

📱 商品分类筛选

html
<!-- 电商商品分类选择 -->
<van-cascader
  v-model="categoryId"
  title="商品分类"
  :options="categoryOptions"
  active-color="#ff6034"
/>

📚 知识分类导航

html
<!-- 文档或知识库分类 -->
<van-cascader
  v-model="topicId"
  title="选择主题"
  :options="topicOptions"
  :field-names="{ text: 'title', value: 'id', children: 'subTopics' }"
/>

⚡ 性能优化小贴士

  1. 数据懒加载:对于大量数据,使用异步加载避免首次渲染卡顿
  2. 合理的层级深度:建议控制在 3-4 层,过深会影响用户体验
  3. 数据缓存:对于相对固定的数据(如地区信息),可以进行本地缓存
  4. 虚拟滚动:当单层选项过多时,考虑使用虚拟滚动优化性能

🎨 设计建议

  • 层级指示:清晰的标签页设计让用户知道当前选择的层级
  • 选中状态:明显的选中状态反馈,让用户清楚自己的选择
  • 加载状态:异步加载时提供友好的加载提示
  • 错误处理:网络异常时提供重试机制和错误提示

🔧 常见问题解决

Q: 如何实现搜索功能? A: 可以通过 options-top 插槽添加搜索框,结合数据过滤实现搜索。

Q: 如何设置默认选中值? A: 设置 v-model 的初始值为目标选项的 value 即可。

Q: 异步加载失败怎么办? A: 在 change 事件中添加错误处理,提供重试按钮或错误提示。

Q: 如何限制选择层级? A: 可以在数据结构中控制 children 的层级深度,或在 change 事件中进行判断。

🎪 高级用法示例

动态禁用选项

javascript
// 根据业务逻辑动态禁用某些选项
const processOptions = (options, parentValue) => {
  return options.map(option => ({
    ...option,
    disabled: shouldDisableOption(option, parentValue),
    children: option.children ? processOptions(option.children, option.value) : []
  }));
};

自定义选项渲染

html
<van-cascader v-model="value" :options="options">
  <template #option="{ option, selected }">
    <div class="custom-option">
      <span>{{ option.text }}</span>
      <van-icon v-if="option.hot" name="fire" color="red" />
      <van-tag v-if="selected" size="mini" type="primary">已选</van-tag>
    </div>
  </template>
</van-cascader>

🔗 相关组件

📚 延伸阅读


💡 小提示:好的级联选择器就像一个优秀的导游,不仅要知道路怎么走,还要让游客在选择的过程中感到轻松愉快。合理运用 Cascader 的各种特性,可以让复杂的数据选择变得简单而有趣!

基于Vant构建的企业级移动端解决方案