
Cascader 級聯選擇器完全指南Element Plus 層級數據選擇的配置、源碼原理與最佳實踐【免費下載鏈接】element-plus A Vue.js 3 UI Library made by Element team項目地址: https://gitcode.com/GitHub_Trending/el/element-plusElement Plus 是 Vue 3 生態中主流的 UI 組件庫本倉庫為 element-plus 官方倉庫。當業務數據具有清晰的層級結構——例如省市區、組織架構、商品分類——時Cascader級聯選擇器是查看與選擇這類數據的標準答案。本文以倉庫中 級聯選擇器官方文檔 為核心骨架結合 cascader 組件源碼、cascader-panel 面板源碼 與 Node 樹節點實現完整講解el-cascader的全部配置項、事件、插槽、暴露方法以及CascaderPanel、CascaderProps的底層原理。讀完本文你將掌握從基礎綁定、禁用、清空、多選、動態加載、搜索過濾到虛擬滾動、自定義插槽的完整實戰方案。一、基礎用法從 options 數組到兩種展開方式Cascader 的核心數據來源是options屬性它是一個嵌套數組。每個節點對象默認使用value、label、children三個字段來描述值、展示文本與子節點。組件內部會把這份純數據轉換成Node節點樹參見 Node 構造函數const { value: valueKey, label: labelKey, children: childrenKey } config const childrenData data[childrenKey] as ChildrenData ... this.value data[valueKey] as CascaderNodeValue this.label data[labelKey] as string this.children (childrenData || []).map((child) new Node(child, config, this))子選項的展開方式由props.expandTrigger控制可選click默認與hover。倉庫示例 basic.vue 同時演示了兩種模式template div classm-4 pChild options expand when clicked (default)/p el-cascader v-modelvalue :optionsoptions changehandleChange / /div div classm-4 pChild options expand when hovered/p el-cascader v-modelvalue :optionsoptions :propsprops changehandleChange / /div /template script langts setup import { ref } from vue const value ref([]) const props { expandTrigger: hover as const, } const handleChange (value) { console.log(value) } const options [ { value: guide, label: Guide, children: [ { value: disciplines, label: Disciplines, children: [ { value: consistency, label: Consistency }, { value: feedback, label: Feedback }, { value: efficiency, label: Efficiency }, { value: controllability, label: Controllability }, ], }, { value: navigation, label: Navigation }, ], }, // ...更多層級 ] /script幾點關鍵細節v-model綁定的值在默認情況下emitPath為true是從根節點到當前節點的整條路徑值數組例如[guide, disciplines, consistency]而不是葉子節點的單個值。change事件在綁定值變化時觸發回調參數即當前值。expandTrigger: hover配合props.hoverThreshold默認 500 毫秒使用鼠標懸停超過閾值才會展開子菜單避免誤觸。該默認值定義在 DefaultProps。二、禁用選項disabled 字段與字段名定制在 option 對象中為某個節點設置disabled: true該節點即被禁用。倉庫示例 option-disabling.vue 中Guide一級節點設置了disabled: true其整棵子樹都不可選擇。默認情況下 Cascader 讀取每個 option 對象中的disabled字段。如果你使用的數據結構用了其他字段名可以通過props.disabled指定同理value、label、children字段名也都可以定制。這一定制能力來自 config.ts 中定義的DefaultPropsvalue: value, label: label, children: children, leaf: leaf, disabled: disabled,而底層的禁用判定邏輯位于 Node.isDisabled它不僅檢查當前節點自身還會在非checkStrictly模式下向上追溯父節點——只要父節點被禁用子孫節點全部視為禁用get isDisabled(): boolean { const { data, parent, config } this const { disabled, checkStrictly } config const isDisabled isFunction(disabled) ? disabled(data, this) : !!data[disabled] return isDisabled || (!checkStrictly !!parent?.isDisabled) }三、清空與自定義清空圖標設置clearable屬性后當有選中值且鼠標懸停在輸入框上時會出現清空圖標點擊即可清空選中值。自 2.11.0 版本起可通過clear-icon屬性自定義清空圖標組件。源碼中該屬性的默認值是內置的CircleClose圖標clearIcon: { type: iconPropType, default: CircleClose, },用法示例見 clear-icon.vueel-cascader v-modelvalue :optionsoptions clearable :clear-iconSomeIcon /自 2.7.7 起點擊清空圖標會觸發clear事件可用來做額外的埋點或狀態重置。四、僅顯示最后一級show-all-levels默認情況下show-all-levels true輸入框中顯示選中項的完整路徑各層級之間用separator分隔默認 / 可通過separator屬性自定義。設置show-all-levels false后輸入框只顯示最后一級的文字。路徑文字的計算邏輯在 Node.calcTextcalcText(allLevels: boolean, separator: string) { const text allLevels ? this.pathLabels.join(separator) : this.label this.text text return text }el-cascader v-modelvalue :optionsoptions :show-all-levelsfalse /五、多選multiple 與標簽折疊多選模式需要把multiple: true寫進props對象。官方文檔特別強調了一個易踩的坑正確寫法必須通過變量綁定template el-cascader :propsprops / /template script langts setup const props { multiple: true } /script錯誤寫法對象字面量直接綁定對 cascader 無效template !-- Object literal binding here is invalid syntax for cascader -- el-cascader :props{ multiple: true } / /template多選模式下所有選中項默認以標簽Tag形式全部展示配合以下屬性可控制折疊行為示例見 multiple-selection.vuecollapse-tags是否折疊超出部分的標簽。true時僅顯示max-collapse-tags個標簽默認 1其余合并為N的折疊文本。max-collapse-tags2.3.10最多顯示的標簽數量默認1使用前提是collapse-tags true。collapse-tags-tooltip鼠標懸停折疊文本時是否以 Tooltip 展示全部選中標簽使用前提同樣是collapse-tags true。max-collapse-tags-tooltip-height2.10.2折疊標簽 Tooltip 的最大高度。el-cascader :optionsoptions :props{ multiple: true } collapse-tags collapse-tags-tooltip :max-collapse-tags3 clearable /從源碼看maxCollapseTags默認值1、collapseTagsTooltip默認false均在 cascader.ts 中定義。六、選擇任意層級checkStrictly在單選中默認只能選葉子節點多選中勾選父節點會聯動勾選其全部葉子節點父節點本身不會被記錄為選中值。當需要父、子節點互不關聯、任意層級都可選擇時設置props.checkStrictly true即可示例見 any-level.vue。checkStrictly影響兩處底層行為禁用判定Node.isDisabled中的(!checkStrictly !!parent?.isDisabled)——開啟后父節點禁用不再連坐子節點。勾選聯動見 Node.doCheckdoCheck(checked: boolean) { if (this.checked checked) return const { checkStrictly, multiple } this.config if (checkStrictly || !multiple) { this.checked checked } else { // bottom up to unify the calculation of the indeterminate state this.broadcast(checked) this.setCheckState(checked) this.emit() } }可以看到checkStrictly true時節點勾選狀態彼此獨立否則通過broadcast自頂向下廣播與emit自底向上回溯完成父子聯動并借助setCheckState計算半選indeterminate狀態。七、動態加載lazy 與 lazyLoad當數據量極大或子級數據依賴服務端按需獲取時可開啟動態加載。設置props.lazy true并實現props.lazyLoad(node, resolve, reject)node當前被點擊展開的節點對象resolve加載完成后的回調必須調用參數為子節點數據數組reject2.11.5 起支持的拒絕回調用于標記加載失敗。更準確地展示節點狀態可以給數據加leaf字段可通過props.leaf自定義字段名來聲明是否為葉子節點不聲明時組件會依據是否還有子節點數據來推斷。推斷邏輯見 Node.isLeafget isLeaf(): boolean { const { data, config, childrenData, loaded } this const { lazy, leaf } config const isLeaf isFunction(leaf) ? leaf(data, this) : data[leaf] return isUndefined(isLeaf) ? lazy !loaded ? false : !(isArray(childrenData) childrenData.length) : !!isLeaf }倉庫示例 dynamic-loading.vue 演示了完整的模擬異步加載流程script langts setup import type { CascaderProps } from element-plus let id 0 const props: CascaderProps { lazy: true, lazyLoad(node, resolve) { const { level } node setTimeout(() { const nodes Array.from({ length: level 1 }).map((item) ({ value: id, label: Option - ${id}, leaf: level 2, })) // Invoke resolve callback to return the child nodes data and indicate the loading is finished. resolve(nodes) }, 1000) }, } /script這里leaf: level 2表示深度達到 2 級后不再繼續加載形成有限深度樹。加載狀態由Node.loading字段驅動默認false加載完成后的子節點通過appendChild掛入節點樹。八、搜索過濾filterable、filter-method 與 before-filter設置filterable后輸入關鍵詞即可檢索選項示例見 filterable.vue。默認匹配規則是節點的 label在show-all-levels true時含父級路徑拼接后的文本即Node.text包含關鍵詞即命中。默認實現就寫在 cascader.tsfilterMethod: { type: definePropType(node: CascaderNode, keyword: string) boolean(Function), default: (node: CascaderNode, keyword: string) node.text.includes(keyword), },自定義搜索邏輯時傳入filter-method函數簽名(node: CascaderNode, keyword: string) boolean返回true表示命中。兩個配套屬性debounce輸入關鍵詞后的防抖延遲毫秒默認300。搜索高頻、數據量大時建議調大避免每次按鍵都執行全樹掃描。before-filter過濾前的鉤子函數參數為將要過濾的關鍵詞。返回false或返回一個被 reject 的 Promise 時本次過濾會被中止。適合做未登錄禁止搜索空關鍵詞直接放行等前置攔截。九、自定義節點內容與搜索建議項9.1 節點自定義內容default 插槽通過默認插槽可自定義下拉面板中每個節點的展示內容作用域中可拿到當前節點的Node對象node和原始數據data。示例 custom-content.vue 在葉子節點旁附加了子節點數量el-cascader :optionsoptions template #default{ node, data } span{{ data.label }}/span span v-if!node.isLeaf ({{ data.children.length }}) /span /template /el-cascadernode.isLeaf即上文所述的葉子判定邏輯可在模板中直接使用。9.2 自定義搜索建議項suggestion-item 插槽2.9.5過濾模式下默認的建議項渲染為匹配路徑文本。使用suggestion-item插槽可完全自定義建議項內容作用域中拿到item即CascaderNode。適合在建議項中高亮關鍵詞、附加圖標等場景示例見 custom-suggestion-item.vue。十、CascaderPanel脫離輸入框的獨立級聯面板CascaderPanel是Cascader的核心面板組件el-cascader的展示與交互幾乎都委托給它。它支持單選、多選、動態加載、任意層級選擇等全部特性但沒有輸入框、清空按鈕等外殼能力適合嵌入自定義彈層或抽屜中示例見 panel.vueel-cascader-panel :optionsoptions :propsprops /面板同樣接收options與props還額外支持virtual-scroll、item-size、height2.14.0三個虛擬滾動屬性。面板向外暴露getCheckedNodes(leafOnly?)與clearCheckedNodes()兩個方法。從組件樹關系看Cascader組合了CascaderPanel與 Input/popper 等外殼組件二者共用 CascaderCommonPropsmodelValue、options、props、virtualScroll、itemSize、height。十一、更多進階能力2.10 系列11.1 自定義標簽tag 插槽2.10.3多選模式下的選中標簽可通過tag插槽自定義作用域提供{ data, deleteTag }deleteTag用于手動移除某個標簽。注意使用自定義標簽后collapse-tags、collapse-tags-tooltip、max-collapse-tags將不再生效折疊能力需自行在插槽內實現。11.2 選中展示策略show-checked-strategy2.10.5多選模式下控制已選值的展示/回填粒度child默認展示所有被選中的葉子節點parent當某個父節點的子節點全部被選中時只展示該父節點更整潔適合整組選擇語義。從源碼看該屬性只接受parent | child兩個枚舉值默認child定義于 cascader.ts。注意它只影響值的展示與回顯策略checkStrictly仍決定勾選時的聯動行為。11.3 點擊節點勾選checkOnClickNode / checkOnClickLeaf / showPrefix2.10.5默認多選模式下只能點擊每行左側的前綴圖標radio/checkbox完成勾選。以下屬性用于調整交互checkOnClickNode是否允許點擊節點文本本身進行勾選/取消勾選需與multiple或checkStrictly搭配使用checkOnClickLeaf是否只對葉子節點啟用點擊勾選默認true即默認點擊葉子也可勾選showPrefix是否顯示前綴圖標默認true。如果通過checkOnClickNode讓整個節點可點可設置false隱藏圖標。對應默認值見 DefaultProps。11.4 自定義下拉頭部與底部header / footer 插槽2.10.5通過header與footer插槽可在下拉面板頂部/底部插入自定義內容如全選/清空按鈕、統計文案示例見 custom-header-footer.vue。十二、大數據量性能優化虛擬滾動2.14.0處理海量選項時設置virtual-scroll為true可開啟虛擬滾動只渲染可視區域內的節點顯著降低 DOM 數量與首幀開銷。兩個配套參數height菜單高度px默認204item-size節點行高px默認34。對應常量定義于 config.tsexport const CASCADER_PANEL_ITEM_SIZE 34 export const CASCADER_PANEL_HEIGHT 204el-cascader :optionsoptions virtual-scroll :height300 :item-size34 /若數據量不大保持默認false即可避免不必要的開銷。示例見 virtual-scroll.vue。十三、搜索建議面板寬度fit-input-width2.14.0過濾模式下建議面板suggestion panel的寬度默認按匹配項的最大寬度動態計算。但若通過suggestion-item插槽自定義了建議項內容其實際渲染文本很可能與label值不一致導致寬度計算錯誤。此時可設置fit-input-width值為true建議面板寬度與輸入框等寬值為數字建議面板寬度固定為該像素值默認false按內容自動計算。官方文檔特別提示fit-input-width只影響搜索時的建議面板寬度不影響默認級聯面板的寬度。示例見 fit-input-width.vue。十四、Cascader 完整 API以下 API 表完整繼承自官方文檔 cascader.md并在源碼處標明了默認值出處。14.1 Cascader Attributes名稱說明類型默認值model-value / v-model綁定值string[] \| number[] \| any—options選項數據value/label鍵名可由CascaderProps定制CascaderOption[][]props配置項見下方 CascaderProps 表CascaderProps{}size輸入框尺寸large \| default \| small—placeholder輸入框占位文本string—disabled是否禁用boolean—clearable是否可清空選中值boolean—clear-icon ^(2.11.0)自定義清空圖標組件string \| ComponentCircleCloseshow-all-levels輸入框是否展示選中值的完整路徑booleantruecollapse-tags多選模式下是否折疊標簽boolean—collapse-tags-tooltip懸停折疊文本時是否展示全部標簽需collapse-tags truebooleanfalsemax-collapse-tags-tooltip-height ^(2.10.2)折疊標簽 Tooltip 最大高度string \| number—separator選項 label 分隔符string / filterable是否可搜索boolean—filter-method自定義搜索邏輯返回布爾值表示是否命中(node, keyword) booleannode.text.includes(keyword)debounce搜索防抖延遲毫秒number300before-filter過濾前鉤子返回false或 rejected Promise 時中止過濾(value: string) boolean() truepopper-class下拉與標簽 Tooltip 的自定義類名stringpopper-style下拉與標簽 Tooltip 的自定義樣式string \| object—teleported彈層是否 teleport 到 bodybooleantrueeffect ^(2.10.5)Tooltip 主題dark \| lightlighttag-type標簽類型success \| info \| warning \| dangerinfotag-effect ^(2.7.8)標簽效果light \| dark \| plainlightvalidate-event是否觸發表單校驗booleantruemax-collapse-tags ^(2.3.10)折疊時最多展示的標簽數需collapse-tags truenumber1empty-values ^(2.7.0)組件的空值定義見 config-providerarray—value-on-clear ^(2.7.0)清空后的返回值見 config-providerstring \| number \| boolean \| Function—persistent ^(2.7.8)下拉失活且為false時是否銷毀下拉booleantruefallback-placements ^(2.8.1)彈層翻轉時的候選位置列表Placement[][bottom-start,bottom,top-start,top,right,left]placement ^(2.8.1)下拉位置top \| top-start \| ... \| right-end等 12 種bottom-startpopper-append-to-body ^(已廢棄)是否將彈層追加到 body定位異常時可設false嘗試booleantrueshow-checked-strategy ^(2.10.5)多選展示策略parent整潔/child每個子項都重要parent \| childchildvirtual-scroll ^(2.14.0)大數據量下是否開啟虛擬滾動booleanfalsefit-input-width ^(2.14.0)建議面板寬度是否等于輸入框數字時固定像素寬度boolean \| numberfalseitem-size ^(2.14.0)虛擬滾動節點行高pxnumber34height ^(2.14.0)虛擬滾動菜單高度pxnumber20414.2 Cascader Events名稱說明類型change綁定值變化時觸發(value: CascaderValue) voidexpand-change展開的選項變化時觸發(value: CascaderValue) voidblur失焦時觸發(event: FocusEvent) voidfocus聚焦時觸發(event: FocusEvent) voidclear ^(2.7.7)點擊清空圖標時觸發() voidvisible-change下拉顯示/隱藏時觸發(value: boolean) voidremove-tag多選模式下移除標簽時觸發(value) void14.3 Cascader Slots名稱說明作用域default自定義級聯節點內容{ node, data }empty無匹配選項時的內容—prefix ^(2.9.4)輸入框前綴內容—suggestion-item ^(2.9.5)搜索建議項自定義內容{ item: CascaderNode }tag ^(2.10.3)自定義多選標簽{ data, deleteTag }header ^(2.10.5)下拉頂部內容—footer ^(2.10.5)下拉底部內容—14.4 Cascader Exposes名稱說明類型getCheckedNodes獲取當前選中節點數組leafOnly為true時僅返回葉子節點默認false(leafOnly?: boolean) CascaderNode[] \| undefinedcascaderPanelRef級聯面板 refComputedRefanytogglePopperVisible ^(2.2.31)切換彈層顯隱(visible?: boolean) voidcontentRef級聯內容區 refComputedRefanypresentText ^(2.8.4)當前選中內容的展示文本ComputedRefstringfocus ^(2.11.8)聚焦輸入框() voidblur ^(2.11.8)使輸入框失焦() void十五、CascaderPanel API15.1 CascaderPanel Attributes名稱說明類型默認值model-value / v-model綁定值string[] \| number[] \| any—options選項數據CascaderOption[][]props配置項CascaderProps{}virtual-scroll ^(2.14.0)是否開啟虛擬滾動booleanfalseitem-size ^(2.14.0)虛擬滾動節點行高pxnumber34height ^(2.14.0)虛擬滾動菜單高度pxnumber20415.2 CascaderPanel Events名稱說明類型change綁定值變化時觸發(value: CascaderValue \| undefined) voidupdate:modelValue綁定值變化時觸發(value: CascaderValue \| undefined) voidexpand-change展開選項變化時觸發(value: CascaderNodePathValue) voidclose關閉面板事件供 Cascader 收起面板判斷() void15.3 CascaderPanel Slots名稱說明作用域default自定義節點內容{ node, data }empty ^(2.8.3)無數據時的面板內容—15.4 CascaderPanel Exposes名稱說明類型getCheckedNodes獲取選中節點數組(leafOnly?: boolean) CascaderNode[] \| undefinedclearCheckedNodes清空選中節點() void十六、CascaderProps 配置詳解props對象統一控制級聯樹的行為語義與組件外殼屬性輸入框、彈層相關分離。其默認值集中定義在 DefaultProps并在運行時與用戶傳入的props合并export const useCascaderConfig (props: { props: CascaderProps }) { return computed(() ({ ...DefaultProps, ...props.props, })) }屬性說明類型默認值expandTrigger展開子選項的觸發方式click \| hoverclickmultiple是否開啟多選booleanfalsecheckStrictly節點勾選狀態是否不影響父/子節點booleanfalseemitPath選中變化時是否發出節點路徑數組false時僅發出節點自身的值booleantruelazy是否動態加載子節點需配合lazyLoadbooleanfalselazyLoad加載子節點數據的方法僅lazy true時生效2.11.5 支持reject參數(node, resolve, reject) void—value指定節點對象中用作值的鍵名stringvaluelabel指定節點對象中用作展示文本的鍵名stringlabelchildren指定節點對象中子節點的鍵名stringchildrendisabled指定節點對象中禁用標記的鍵名也支持函數string \| (data, node) booleandisabledleaf指定節點對象中葉子標記的鍵名也支持函數string \| (data, node) booleanleafhoverThresholdhover 展開的懸停閾值毫秒number500checkOnClickNode ^(2.10.5)點擊節點時是否勾選/取消勾選booleanfalsecheckOnClickLeaf ^(2.10.5)點擊葉子節點時是否勾選/取消勾選booleantrueshowPrefix ^(2.10.5)是否顯示 radio/checkbox 前綴圖標booleantrue其中emitPath直接決定v-model綁定值的形式為true默認時綁定的是路徑值數組為false時只綁定當前選中節點的value。對應實現見 Node.valueByOptionget valueByOption() { return this.config.emitPath ? this.pathValues : this.value }十七、類型聲明與 Node 節點模型官方文檔末尾給出了完整的 TypeScript 聲明見 cascader.md 的 Type Declarations 小節核心類型在源碼 types.ts 中同樣可見type CascaderNodeValue string | number | Recordstring, any type CascaderNodePathValue CascaderNodeValue[] type CascaderValue | CascaderNodeValue | CascaderNodePathValue | (CascaderNodeValue | CascaderNodePathValue)[] type Resolve (data: any) void type ExpandTrigger click | hover type LazyLoad (node: Node, resolve: Resolve, reject: () void) void type isDisabled (data: CascaderOption, node: Node) boolean type isLeaf (data: CascaderOption, node: Node) boolean interface CascaderOption extends Recordstring, unknown { label?: string value?: CascaderNodeValue children?: CascaderOption[] disabled?: boolean leaf?: boolean } interface CascaderProps { expandTrigger?: ExpandTrigger multiple?: boolean checkStrictly?: boolean emitPath?: boolean lazy?: boolean lazyLoad?: LazyLoad value?: string label?: string children?: string disabled?: string | isDisabled leaf?: string | isLeaf hoverThreshold?: number }樹節點模型Node即公開類型CascaderNode的完整結構定義在 node.ts 中理解它有助于掌握組件的內部運行機制只讀元數據uid全局自增唯一 id、level層級根節點為 1、value、label、pathNodes/pathValues/pathLabels從根到當前節點的完整路徑狀態字段checked是否勾選、indeterminate半選狀態、loading動態加載中、loaded子數據是否已加載派生屬性isDisabled自身及父鏈禁用判定、isLeaf葉子判定、valueByOption按emitPath決定取值形式核心方法calcText(allLevels, separator)計算展示文本、broadcast/emit/onParentCheck/onChildCheck/setCheckState/doCheck父子勾選聯動與半選計算。這套節點模型將數據與狀態解耦options是靜態數據Node負責在運行時維護勾選、加載、展開等交互狀態這也是getCheckedNodes、presentText等暴露方法能即時反映當前狀態的根本原因。十八、實戰小結按場景選擇配置省市區/組織架構單選options 默認配置即可必要時props.emitPath false簡化綁定值多選且值很多props.multiple truecollapse-tagsmax-collapse-tagscollapse-tags-tooltip追求整潔可加show-checked-strategyparent父子層級可選props.checkStrictly true配合checkOnClickNode提升點擊體驗服務端按需加載props.lazy trueprops.lazyLoad用leaf字段聲明葉子大數據量virtual-scroll 按需調整height/item-size需要完全自定義彈層內容default、tag、header、footer、suggestion-item插槽組合使用。文中所有演示均可在倉庫的 docs/examples/cascader 目錄找到對應的可運行示例源碼級默認值可查閱 cascader.ts、config.ts 與 node.ts。【免費下載鏈接】element-plus A Vue.js 3 UI Library made by Element team項目地址: https://gitcode.com/GitHub_Trending/el/element-plus創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考