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構建的企業級移動端解決方案