# How to Use the Element UI Cascader Component for Multi-Level Selection and Data Filtering

> Master the Element UI Cascader for advanced multi-level selection and data filtering. Learn to configure props for dynamic loading, tags, and more to enhance your app's UI.

- Repository: [饿了么前端/element](https://github.com/ElemeFE/element)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The Element UI Cascader component renders hierarchical data as nested selectable menus and supports real-time filtering, multiple selection via tags, and on-demand data loading through configurable props defined in [`cascader.vue`](https://github.com/ElemeFE/element/blob/main/cascader.vue) and [`cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/cascader-panel.vue).**

The **Cascader** component (`ElCascader`) in the ElemeFE/element repository provides a complete solution for multi-level selection and data filtering in Vue.js applications. By combining a wrapper component that manages the input field and search logic with a dedicated panel component that renders nested menus, you can handle complex tree-structured data with lazy loading and custom filtering methods.

## Component Architecture

The implementation splits responsibilities between two coordinated Vue components to separate UI chrome from selection logic.

**ElCascader** ([`packages/cascader/src/cascader.vue`](https://github.com/ElemeFE/element/blob/main/packages/cascader/src/cascader.vue)) serves as the wrapper, managing the input field, selected tags, dropdown visibility via `toggleDropDownVisible()`, and the filtering handler. **ElCascaderPanel** ([`packages/cascader-panel/src/cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/packages/cascader-panel/src/cascader-panel.vue)) handles the rendering of nested option menus, node state management, keyboard navigation via `handleKeyDown()`, and lazy loading execution.

The panel defines the **DefaultProps** schema that governs how each node is interpreted: `value`, `label`, `children`, `leaf`, and `disabled`. These field mappings allow you to adapt the component to various API data structures without transforming your dataset beforehand.

## Basic Implementation

At minimum, bind an options array to the `options` prop and configure the `props` object to define which fields contain children and display labels.

```html
<template>
  <el-cascader
    v-model="selected"
    :options="options"
    :props="cascaderProps"
    placeholder="Select region">
  </el-cascader>
</template>

<script>
export default {
  data() {
    return {
      selected: [],
      options: [
        {
          value: 'zhejiang',
          label: 'Zhejiang',
          children: [
            { value: 'hangzhou', label: 'Hangzhou' },
            { value: 'ningbo', label: 'Ningbo' }
          ]
        },
        {
          value: 'jiangsu',
          label: 'Jiangsu',
          children: [
            { value: 'nanjing', label: 'Nanjing' }
          ]
        }
      ],
      cascaderProps: {
        expandTrigger: 'click',
        value: 'value',
        label: 'label',
        children: 'children'
      }
    };
  }
};
</script>

```

## Enabling Multi-Level Selection and Multiple Values

To activate **multiple selection**, set `multiple: true` inside the `props` configuration object. This transforms the component into a tag-based selector where users can choose multiple leaf nodes across different branches.

```javascript
cascaderProps: {
  multiple: true,        // Enables tag-based multi-selection
  emitPath: false,       // Returns only leaf values instead of full path arrays
  checkStrictly: false   // Restricts selection to leaf nodes only when false
}

```

The wrapper component stores selection state in `checkedValue` and `checkedNodes`, rendering selected items as removable tags in the input field. When `emitPath` is `true` (default), the component returns an array representing the full hierarchy path; when `false`, it emits only the leaf node value.

## Configuring Data Filtering

Enable search functionality by adding the `filterable` prop to `ElCascader`. This displays a text input that triggers a debounced `filterHandler`, which calls `getSuggestions()` (implemented around lines 444-449 in [`cascader.vue`](https://github.com/ElemeFE/element/blob/main/cascader.vue)) to generate matching results.

By default, filtering performs a substring match against node text. Override this behavior by providing a **custom `filterMethod`** that receives the node object and keyword string:

```javascript
methods: {
  filterMethod(node, keyword) {
    return node.label.toLowerCase().includes(keyword.toLowerCase());
  }
}

```

```html
<el-cascader
  :options="options"
  :props="cascaderProps"
  :filter-method="filterMethod"
  filterable>
</el-cascader>

```

## Lazy Loading Large Hierarchies

For datasets too large to load upfront, configure **lazy loading** by setting `lazy: true` and providing a `lazyLoad` function in your props. The panel invokes this method (implementation spans lines 998-1035 in [`cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/cascader-panel.vue)) whenever a user expands a node without cached children.

```javascript
cascaderProps: {
  lazy: true,
  lazyLoad(node, resolve) {
    const { level } = node;
    // Simulate API call
    setTimeout(() => {
      const nodes = Array.from({ length: level + 1 }).map((_, index) => ({
        value: `${node.value}-${index}`,
        label: `Option ${node.value}-${index}`,
        leaf: level >= 2
      }));
      resolve(nodes);
    }, 500);
  }
}

```

The `lazyLoad` function receives the parent `node` and a `resolve` callback. You must call `resolve` with an array of child node objects matching the DefaultProps schema. Set `leaf: true` on nodes without further descendants to prevent expansion arrows.

## Accessing Selected Node Data

Expose the underlying node objects for advanced validation or display logic by calling the **public API method** `getCheckedNodes(leafOnly)` on the Cascader instance. When `leafOnly` is `true`, the method returns only leaf nodes; when `false`, it includes intermediate selected nodes.

```javascript
// In your component method
const nodes = this.$refs.cascader.getCheckedNodes(true);
console.log(nodes.map(n => n.label));

```

## Summary

- **Two-component architecture**: [`cascader.vue`](https://github.com/ElemeFE/element/blob/main/cascader.vue) handles input/filtering while [`cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/cascader-panel.vue) renders menus and manages selection state.
- **Configurable mapping**: The `props` object defines field names for `value`, `label`, `children`, and enables features like `multiple` and `emitPath`.
- **Built-in filtering**: Enable `filterable` for search support; customize matching logic via `filterMethod` called within `getSuggestions()`.
- **Performance optimization**: Use `lazy` loading with a `lazyLoad` function to fetch child data on demand, implemented in the panel's store management logic.

## Frequently Asked Questions

### How do I enable multiple selection in the Element UI Cascader?

Set `props.multiple` to `true` in your configuration object. This activates the tag-based interface in [`cascader.vue`](https://github.com/ElemeFE/element/blob/main/cascader.vue), allowing users to select multiple values across different branches. The component stores selections in `checkedNodes` and renders them as removable tags in the input field.

### Can I search and filter options across all levels of the hierarchy?

Yes. Add the `filterable` prop to enable the search input, which triggers the internal `filterHandler`. The wrapper calls `getSuggestions()` to filter the tree. For custom matching logic (such as case-insensitive search or pinyin matching), provide a `filterMethod` function that receives `(node, keyword)` and returns a boolean.

### How does lazy loading work for large datasets?

Configure `props.lazy` as `true` and provide a `lazyLoad` function. When a user expands a node without cached children, the panel component calls your loader with the node and a `resolve` callback. Call `resolve(childNodesArray)` to populate the menu dynamically, as implemented in lines 998-1035 of [`cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/cascader-panel.vue).

### What is the difference between ElCascader and ElCascaderPanel?

**ElCascader** ([`packages/cascader/src/cascader.vue`](https://github.com/ElemeFE/element/blob/main/packages/cascader/src/cascader.vue)) is the high-level wrapper that manages the input box, dropdown visibility via `toggleDropDownVisible()`, filtering logic, and tag rendering. **ElCascaderPanel** ([`packages/cascader-panel/src/cascader-panel.vue`](https://github.com/ElemeFE/element/blob/main/packages/cascader-panel/src/cascader-panel.vue)) is the presentational component that renders the nested column menus, handles keyboard navigation, and manages the internal `Store` of node states.