Skip to content

Cascader

A general-purpose cascading selector.

Basic Usage

Default click Trigger子menu
hover Trigger子menu
option值
[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Default click Trigger子menu</span>
      <b-cascader v-model="selected" :options="options" @change="handleChange"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">hover Trigger子menu</span>
      <b-cascader
        v-model="selected"
        :options="options"
        :props="{ expandTrigger: 'hover' }"
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">option值</span>
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Disabled State

Use disabled to disable the cascader.

Disabled项
全部Disabled
option值
[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Disabled项</span>
      <b-cascader v-model="selected" :options="options" @change="handleChange"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">全部Disabled</span>
      <b-cascader
        v-model="selected"
        :options="options"
        disabled
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">option值</span>
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    disabled: true,
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Clearable

The selection can be cleared.

[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader
        v-model="selected"
        :options="options"
        clearable
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Show Last Level Only

The input can be configured to show only the last level label.

[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader
        v-model="selected"
        :options="options"
        clearable
        :show-all-levels="false"
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Multiple Selection

Set props.multiple to enable multi-selection.

Default show所有tag
collapseshowtag
option值
[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Default show所有tag</span>
      <b-cascader
        v-model="selected"
        :options="options"
        :props="{ multiple: true }"
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">collapseshowtag</span>
      <b-cascader
        v-model="selected"
        :options="options"
        :props="{ multiple: true }"
        collapse-tags
        @change="handleChange"
      ></b-cascader>
    </div>
    <div class="block" style="width: calc(100% - 500px); margin-right: 20px">
      <span class="demonstration">option值</span>
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Select Any Level

In single mode, only leaf nodes can be selected. In multi mode, checking a parent node selects its leaf nodes. Enable this feature to decouple parent-child selection and allow selecting any level.

Set props.checkStrictly = true to decouple parent-child selection, allowing independent selection at any level.

Single select选择任意一级option
[]
Multi-select选择任意一级option
[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Single select选择任意一级option</span>
      <b-cascader
        v-model="selected1"
        :options="options"
        :props="{ checkStrictly: true }"
        @change="handleChange"
      ></b-cascader>
      <div class="mt-5">{{ selected1 }}</div>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Multi-select选择任意一级option</span>
      <b-cascader
        v-model="selected2"
        :options="options"
        :props="{ multiple: true, checkStrictly: true }"
        collapse-tags
        @change="handleChange"
      ></b-cascader>
      <div class="mt-5">{{ selected2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected1 = ref([])
const selected2 = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Dynamic Loading

Dynamically load child options when a level is selected. Enable with lazy and configure the data source method via lazyload.

The lazyload method has two parameters: the first parameter node is the currently clicked node, the second resolve is the callback that must be called when data loading is complete. For more accurate display of node status, you can also mark node data with a leaf indicator (the default field is leaf, which can be modified via props.leaf). Otherwise, it simply checks whether the node has children to determine whether it is a leaf node.

[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader v-model="selected" :props="props"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

let id = 0

const selected = ref([])
const props = {
  lazy: true,
  lazyLoad(node, resolve) {
    const { level } = node
    setTimeout(() => {
      const nodes = Array.from({ length: level + 1 }).map(() => ({
        value: ++id,
        label: `option${id}`,
        leaf: level >= 2
      }))
      // 通过callresolve将子节点数据返回,Noticecomponent数据Load完成
      resolve(nodes)
    }, 1000)
  }
}
</script>

Searchable

Quickly search and select options. Set filterable to true to enable search. By default, it matches options whose label (or all ancestor labels, depending on show-all-levels) contains the search text.

You can also use filter-method to customize the search logic. It accepts a function with two parameters: the node and the search keyword, and returns a boolean to indicate whether it matches.

Single select可Search
[]
Multi-select可Search
[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Single select可Search</span>
      <b-cascader
        v-model="selected1"
        placeholder="试试Search:鼓楼"
        :options="options"
        filterable
      ></b-cascader>
      <div class="mt-5">{{ selected1 }}</div>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <span class="demonstration">Multi-select可Search</span>
      <b-cascader
        v-model="selected2"
        placeholder="试试Search:鼓楼"
        :options="options"
        :props="{ multiple: true }"
        collapse-tags
        filterable
        :filter-method="filterMethod"
      ></b-cascader>
      <div class="mt-5">{{ selected2 }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected1 = ref([])
const selected2 = ref([])

function filterMethod(node, keyword) {
  return node.label.includes(keyword) && node.parent && node.parent.label === 'Xuzhou'
}
</script>

Custom Options

Option content can be customized. The scoped slot receives two props: node (the current Node object) and data (the node data).

[]
<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader :options="options">
        <template #default="{ node, data }">
          <span>{{ data.label }}</span>
          <span v-if="!node.isLeaf">({{ data.children.length }})</span>
        </template>
      </b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])

function handleChange(value) {
  console.log(value)
}
</script>

Sizes

<template>
  <div flex>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader :options="options" size="large"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader :options="options"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader :options="options" size="small"></b-cascader>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <b-cascader :options="options" size="mini"></b-cascader>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
</script>

Cascader Panel

You can use a panel display instead of the popper dialog. Usage is the same as cascader.

[]
<template>
  <div flex>
    <div class="block" style="margin-right: 20px">
      <b-cascader-panel v-model="selected" :options="options"></b-cascader-panel>
    </div>
    <div class="block" style="width: 220px; margin-right: 20px">
      <div class="mt-5">{{ selected }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const options = [
  {
    value: 'nanjing',
    label: 'Nanjing',
    children: [
      {
        value: 'xuanwu',
        label: '玄武区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'jianye',
        label: '建邺区'
      }
    ]
  },
  {
    value: 'xuzhou',
    label: 'Xuzhou',
    children: [
      {
        value: 'tongshan',
        label: '铜山区'
      },
      {
        value: 'gulou',
        label: 'Gulou District'
      },
      {
        value: 'yunlong',
        label: 'Yunlong District',
        children: [
          { value: 'dalonghu', label: '大龙湖街道' },
          { value: 'guozhuanglu', label: '郭庄路街道' },
          { value: 'lvdi', label: '绿地商务城' },
          { value: 'jinlonghu', label: '金龙湖街道' }
        ]
      },
      {
        value: 'jiawang',
        label: 'Jiawang District'
      },
      { value: 'peixian', label: '沛县' },
      { value: 'fengxian', label: '丰县' },
      { value: 'pizhou', label: '邳州City' },
      { value: 'xinyi', label: 'New沂City' }
    ]
  }
]
const selected = ref([])
</script>

Cascader Props

ParameterDescriptionTypeOptionsDefault
value / v-modelBinding value of the selected item-
optionsData source for options. Key names can be configured via the Props propertyarray
propsConfiguration options, see the table belowobject
sizeSizestringmedium / small / mini
placeholderInput placeholder textstringPlease select
disabledDisabledbooleanfalse
clearableWhether to support clearing optionsbooleanfalse
show-all-levelsWhether to show the full path of the selected value in the inputbooleantrue
collapse-tagsWhether to collapse tags in multi-select modeboolean-false
separatorOption separatorstring' / '
filterableWhether options are searchableboolean
filter-methodCustom search logic. The first parameter is the node node, the second is the search keyword keyword. Returns a boolean indicating whether it matchesfunction(node, keyword)--
debounceDebounce delay for search keyword input, in millisecondsnumber300
before-filterHook before filtering. The parameter is the input value. If it returns false or a rejected Promise, filtering stopsfunction(value)
popper-classCustom class name for the overlaystring

Cascader Events

Event NameDescriptionCallback Parameters
changeTriggered when the selected node changesValue of the selected node
expand-changeTriggered when the expanded node changesArray of parent option values
blurTriggered when focus is lost(event: Event)
focusTriggered when focus is gained(event: Event)
visible-changeTriggered when the dropdown appears/hidestrue when appearing, false when hiding
remove-tagTriggered when a tag is removed in multi-select modeValue of the node corresponding to the removed tag

Cascader Methods

Method NameDescriptionParameter
getCheckedNodesGet the selected nodes(leafOnly) Whether to only return leaf nodes, default is false

Cascader Slots

NameDescription
-Custom content for option nodes. Parameters are { node, data }, the Node object and data of the current node respectively
emptyContent when no matching options are found

CascaderPanel Attributes

ParameterDescriptionTypeOptionsDefault
value / v-modelBinding value of the selected item-
optionsData source for options. Key names can be configured via the Props propertyarray
propsConfiguration options, see the table belowobject

CascaderPanel Events

Event NameDescriptionCallback Parameters
changeTriggered when the selected node changesValue of the selected node
expand-changeTriggered when the expanded node changesArray of parent option values

CascaderPanel Methods

Method NameDescriptionParameter
getCheckedNodesGet the array of selected nodes(leafOnly) Whether to only return leaf nodes, default is false
clearCheckedNodesClear the selected nodes-

CascaderPanel Slots

NameDescription
-Custom content for option nodes. Parameters are { node, data }, the Node object and data of the current node respectively

Props

ParameterDescriptionTypeOptionsDefault
expandTriggerTrigger mode for sub-menus to expandstringclick / hover'click'
multipleWhether to support multi-selectboolean-false
checkStrictlyWhether to strictly enforce parent-child node independenceboolean-false
emitPathWhen the selected node changes, whether to return an array composed of values from each menu level where the node is located. If set to false, only the value of that node is returnedboolean-true
lazyWhether to dynamically load child nodes. Must be used with the lazyLoad methodboolean-false
lazyLoadMethod for loading dynamic data, only effective when lazy is truefunction(node, resolve), node is the currently clicked node, resolve is the callback that must be called when data loading is complete--
valueSpecifies which property of the option object to use as the option valuestring'value'
labelSpecifies which property of the option object to use as the option labelstring'label'
childrenSpecifies which property of the option object to use as the option's childrenstring'children'
disabledSpecifies which property of the option object to use as the option's disabled statestring'disabled'
leafSpecifies which property of the option object to use as the leaf node indicatorstring'leaf'