Cascader 级联选择器
当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择。
基础用法
这里我们提供了两种触发方式
将`options`属性赋值为选项数组即可渲染出一个级联选择器。通过`props.expandTrigger`属性可以定义展开子级菜单的触发方式。
点击时展开子级菜单 (默认)
鼠标悬浮时展开子级菜单
<template>
<div class="m-4">
<p>Child options expand when clicked (default)</p>
<el-cascader v-model="value" :options="options" @change="handleChange" />
</div>
<div class="m-4">
<p>Child options expand when hovered</p>
<el-cascader
v-model="value"
:options="options"
:props="props"
@change="handleChange"
/>
</div>
</template>
<script lang="ts" 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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
禁用选项
通过在数据源中设置 `disabled` 字段来声明该选项是禁用的
在本例中,`options` 数组的第一个项目有一个 `disabled: true` 字段,因此它是禁用的。默认情况下,级联选择器会检查每个选项对象中的 `disabled` 字段;如果您正在使用另一个字段名来指示选项是否被禁用,您可以在 `props.disabled` 属性中指定它(详情请参见下面的API表)。当然,字段名 `value`、`label` 和 `children` 也可以以同样的方式进行自定义。
<template>
<el-cascader :options="options" />
</template>
<script lang="ts" setup>
const options = [
{
value: 'guide',
label: 'Guide',
disabled: true,
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
可清空
为 `el-cascader` 设置 `clearable` 属性,则当选中并悬浮时会出现一个清除图标。
<template>
<el-cascader :options="options" clearable />
</template>
<script lang="ts" setup>
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
自定义清除图标 2.11.0
您可以通过设置 `clear-icon` 属性来自定义清除图标。
<template>
<el-cascader
:options="options"
clearable
:clear-icon="CloseBold"
placeholder="Custom clear icon"
/>
</template>
<script lang="ts" setup>
import { CloseBold } from '@element-plus/icons-vue'
const options = [
{
value: 'guide',
label: 'Guide',
children: [
{
value: 'disciplines',
label: 'Disciplines',
},
],
},
]
</script>
仅显示最后一级
可以仅在输入框中显示选中值的最后一级,而不是显示所有级别。
`show-all-levels` 属性定义是否显示所有级别。如果为 `false`,则只显示最后一级。
<template>
<el-cascader :options="options" :show-all-levels="false" />
</template>
<script lang="ts" setup>
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
多选
在标签中添加 `:props="props"` 并设置数据 `props = { multiple: true }` 来使用多选。
Do
<template>
<el-cascader :props="props" />
</template>
<script lang="ts" setup>
const props = { multiple: true }
</script>
Don't do
<template>
<!-- Object literal binging here is invalid syntax for cascader -->
<el-cascader :props="{ multiple: true }" />
</template>
在使用多选时,默认会显示所有选中的标签。您可以设置 `collapse-tags = true` 来折叠选中的标签。您可以设置 `max-collapse-tags` 来显示最大标签数,默认为 1。您可以使用 `collapse-tags-tooltip` 属性,在鼠标悬停折叠文本上时查看它们。
显示所有标签 (默认)
折叠标签
折叠标签提示
最大折叠标签数
<template>
<div class="m-4">
<p>Display all tags (default)</p>
<el-cascader :options="options" :props="props" clearable />
</div>
<div class="m-4">
<p>Collapse tags</p>
<el-cascader :options="options" :props="props" collapse-tags clearable />
</div>
<div class="m-4">
<p>Collapse tags tooltip</p>
<el-cascader
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
clearable
/>
</div>
<div class="m-4">
<p>Max Collapse Tags</p>
<el-cascader
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="3"
clearable
/>
</div>
</template>
<script lang="ts" setup>
const props = { multiple: true }
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' },
],
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' },
],
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' },
],
},
],
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' },
],
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' },
],
},
],
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: 'Los Angeles' },
{ value: 27, label: 'Washington' },
],
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' },
],
},
],
},
]
</script>
选择任意一级选项
在单选模式下,只有叶子节点才能被选中,在多选模式下,选中父节点会导致叶子节点最终被选中。启用此功能后,可以使父子节点不关联,您可以选择任意级别的选项。
设置 `props.checkStrictly = true` 来使得节点的选中状态不影响其父节点和子节点,然后您可以选择任意级别的选项。
选择任意级别的选项(单选)
选择任意级别的选项(多选)
<template>
<div class="m-4">
<p>Select any level of options (Single selection)</p>
<el-cascader :options="options" :props="props1" clearable />
</div>
<div class="m-4">
<p>Select any level of options (Multiple selection)</p>
<el-cascader :options="options" :props="props2" clearable />
</div>
</template>
<script lang="ts" setup>
const props1 = {
checkStrictly: true,
}
const props2 = {
multiple: true,
checkStrictly: true,
}
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
动态加载
选中一个节点时动态加载其子节点。
设置 `lazy = true` 来使用动态加载,并且您必须通过 `lazyload` 来指定如何加载数据源。`lazyload` 有两个参数,第一个参数 `node` 是当前点击的节点,第二个参数 `resolve` 是一个回调函数,表示加载完成,必须调用。为了更准确地显示节点的状态,您可以添加一个 `leaf` 字段(可以通过 `props.leaf` 修改)来指示它是否是叶子节点。否则,将通过是否有子节点来推断。
<template>
<el-cascader :props="props" />
</template>
<script lang="ts" 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>
可筛选
通过关键字搜索和选择选项。
在 `el-cascader` 中添加 `filterable` 即可启用过滤功能。级联选择器将匹配标签或父级标签(根据 `show-all-levels`)包含输入关键字的节点。当然,您也可以通过 `filter-method` 自定义搜索逻辑,它接受一个函数,第一个参数是 `node`,第二个是 `keyword`,需要返回一个布尔值,表示是否命中。
可过滤(单选)
可过滤(多选)
<template>
<div class="m-4">
<p>Filterable (Single selection)</p>
<el-cascader
placeholder="Try searchingL Guide"
:options="options"
filterable
/>
</div>
<div class="m-4">
<p>Filterable (Multiple selection)</p>
<el-cascader
placeholder="Try searchingL Guide"
:options="options"
:props="props"
filterable
/>
</div>
</template>
<script lang="ts" setup>
const props = {
multiple: true,
}
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
自定义选项内容
您可以自定义级联选择器节点的内容。
您可以通过 `scoped slot` 自定义级联选择器节点的内容。您将可以访问作用域中的 `node` 和 `data`,分别代表当前节点的 Node 对象和节点数据。
<template>
<el-cascader :options="options">
<template #default="{ node, data }">
<span>{{ data.label }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</template>
<script lang="ts" setup>
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
自定义建议项 2.9.5
您可以通过 `suggestion-item` 插来自定义过滤建议项。您将可以访问作用域中的 `item`,代表建议项。
<template>
<el-cascader :options="options" filterable placeholder="Try searching: Guide">
<template #suggestion-item="{ item }">
<span>🔍 {{ item.pathLabels.join(' > ') }}</span>
</template>
</el-cascader>
</template>
<script lang="ts" setup>
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
级联面板
`CascaderPanel` 是 `Cascader` 的核心组件,具有单选、多选、动态加载等多种功能。
就像 `el-cascader` 一样,您可以通过 `options` 设置备选选项,并通过 `props` 启用其他功能,详情请参见下面的 API 表格。
- 指南
- 组件
- 资源
<template>
<el-cascader-panel style="width: fit-content" :options="options" />
</template>
<script lang="ts" setup>
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',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
{
value: 'top nav',
label: 'Top Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
{
value: 'color',
label: 'Color',
},
{
value: 'typography',
label: 'Typography',
},
{
value: 'icon',
label: 'Icon',
},
{
value: 'button',
label: 'Button',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
{
value: 'checkbox',
label: 'Checkbox',
},
{
value: 'input',
label: 'Input',
},
{
value: 'input-number',
label: 'InputNumber',
},
{
value: 'select',
label: 'Select',
},
{
value: 'cascader',
label: 'Cascader',
},
{
value: 'switch',
label: 'Switch',
},
{
value: 'slider',
label: 'Slider',
},
{
value: 'time-picker',
label: 'TimePicker',
},
{
value: 'date-picker',
label: 'DatePicker',
},
{
value: 'datetime-picker',
label: 'DateTimePicker',
},
{
value: 'upload',
label: 'Upload',
},
{
value: 'rate',
label: 'Rate',
},
{
value: 'form',
label: 'Form',
},
],
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table',
},
{
value: 'tag',
label: 'Tag',
},
{
value: 'progress',
label: 'Progress',
},
{
value: 'tree',
label: 'Tree',
},
{
value: 'pagination',
label: 'Pagination',
},
{
value: 'badge',
label: 'Badge',
},
],
},
{
value: 'notice',
label: 'Notice',
children: [
{
value: 'alert',
label: 'Alert',
},
{
value: 'loading',
label: 'Loading',
},
{
value: 'message',
label: 'Message',
},
{
value: 'message-box',
label: 'MessageBox',
},
{
value: 'notification',
label: 'Notification',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu',
},
{
value: 'tabs',
label: 'Tabs',
},
{
value: 'breadcrumb',
label: 'Breadcrumb',
},
{
value: 'dropdown',
label: 'Dropdown',
},
{
value: 'steps',
label: 'Steps',
},
],
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog',
},
{
value: 'tooltip',
label: 'Tooltip',
},
{
value: 'popover',
label: 'Popover',
},
{
value: 'card',
label: 'Card',
},
{
value: 'carousel',
label: 'Carousel',
},
{
value: 'collapse',
label: 'Collapse',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
{
value: 'sketch',
label: 'Sketch Templates',
},
{
value: 'docs',
label: 'Design Documentation',
},
],
},
]
</script>
自定义标签 2.10.3
您可以自定义标签。
在`el-cascader`的插槽中插入自定义标签。`collapse-tags`,`collapse-tags-tooltip`,`max-collapse-tags`将不会生效。
使用插槽可以更灵活地控制显示。
只显示顶级标签
<template>
<div class="m-4">
<p>Using slots allows for more flexible control over the display.</p>
<el-cascader :options="options" :props="props" clearable>
<template #tag="{ data }">
<el-tag
v-for="(item, index) in getTags(data)"
:key="item"
:color="index % 2 === 0 ? '#FFDE0A' : ''"
>
{{ item }}
</el-tag>
</template>
</el-cascader>
<p>Display top-level tags only</p>
<el-cascader :options="options" :props="props" clearable>
<template #tag="{ data }">
<el-tag v-for="item in getTopLevelTags(data)" :key="item">
{{ item }}
</el-tag>
</template>
</el-cascader>
</div>
</template>
<script lang="ts" setup>
import type { Tag } from 'element-plus'
const props = { multiple: true }
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' },
],
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' },
],
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' },
],
},
],
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' },
],
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' },
],
},
],
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: 'Los Angeles' },
{ value: 27, label: 'Washington' },
],
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' },
],
},
],
},
]
const getTags = (data: Tag[]) => {
return data.map((item) => item.text)
}
const getTopLevelTags = (data: Tag[]) => {
const set: Set<string> = new Set()
for (const datum of data) {
let parent = datum.node?.parent
while (parent && parent.level !== 1) {
parent = parent.parent
}
const label = parent?.data?.label
label && set.add(label)
}
return [...set]
}
</script>
显示选中策略 2.10.5
控制在多选模式下如何显示选中的值。
在多选模式下,您可以使用 `show-checked-strategy` 来控制选定值的显示方式。默认策略是 `child`,它会显示所有选中的子节点。`parent` 策略仅在其所有子节点都被选中时才显示父节点。
策略:child(默认,显示所有选中的子节点)
策略:parent(仅当所有子节点都被选中时显示父节点)
<template>
<div class="m-4">
<p>Strategy: child (default, show all selected child nodes)</p>
<el-cascader
v-model="value1"
:options="options"
:props="props"
show-checked-strategy="child"
clearable
@change="handleChange1"
/>
</div>
<div class="m-4">
<p>
Strategy: parent (show only parent nodes when all children are selected)
</p>
<el-cascader
v-model="value2"
:options="options"
:props="props"
show-checked-strategy="parent"
clearable
@change="handleChange2"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value1 = ref([])
const value2 = ref([])
const props = {
multiple: true,
}
const handleChange1 = (value) => {
console.log('Child strategy:', value)
}
const handleChange2 = (value) => {
console.log('Parent strategy:', value)
}
const options = [
{
value: 'guide',
label: 'Guide',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: 'Consistency',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
],
},
]
</script>
点击选中节点 2.10.5
仅使用 `multiple` 或 `checkStrictly` 属性。
您可以添加 `checkOnClickNode` 来除了前缀图标外,还能点击节点来选中。
使用 `showPrefix` 切换前缀的可见性。
添加 `checkOnClickLeaf` 仅选中叶子节点(最后的子节点),默认启用。
checkStrictly | 单选模式
多选模式
<template>
<div class="flex flex-col items-center">
<el-switch
v-model="showPrefix"
active-text="show prefix"
inactive-text="hide prefix"
/>
<div class="flex flex-wrap">
<div class="m-4">
<p>checkStrictly | Single mode</p>
<el-cascader
v-model="value"
:options="options"
:props="props1"
clearable
/>
</div>
<div class="m-4">
<p>Multiple mode</p>
<el-cascader
v-model="value2"
show-checked-strategy="parent"
:options="options"
:props="props2"
clearable
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
const value = ref()
const value2 = ref()
const showPrefix = ref(true)
const props1 = computed(() => ({
showPrefix: showPrefix.value,
checkStrictly: true,
checkOnClickNode: true,
}))
const props2 = computed(() => ({
showPrefix: showPrefix.value,
multiple: true,
checkOnClickNode: true,
}))
const options = [
{
value: 'guide',
label: 'Guide',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: 'Consistency',
},
],
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation',
},
],
},
],
},
{
value: 'component',
label: 'Component',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout',
},
],
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio',
},
],
},
],
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components',
},
],
},
]
</script>
自定义页眉和页脚 2.10.5
您可以使用插槽来自定义下拉菜单的页眉和页脚。
使用插槽来自定义内容。
自定义页眉内容
自定义页脚内容
<template>
<div class="demo">
<div>
<p>Custom header content</p>
<el-cascader
v-model="value"
popper-class="custom-header"
:options="options"
:props="props"
clearable
>
<template #header>
<el-checkbox
v-model="checkAll"
:indeterminate="indeterminate"
@change="handleCheckAll"
>
All
</el-checkbox>
</template>
</el-cascader>
</div>
<div>
<p>Custom footer content</p>
<el-cascader v-model="value" :options="options" :props="props" clearable>
<template #footer>
<el-button link size="small" @click="handleClear"> Clear </el-button>
</template>
</el-cascader>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import type { CascaderOption, CheckboxValueType } from 'element-plus'
const props = { multiple: true }
const checkAll = ref(false)
const indeterminate = ref(false)
const value = ref<string[][]>([])
const options = ref([
{
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' },
],
},
],
},
])
const getAllValuePaths = computed(() => {
const result: string[][] = []
const queue: { node: CascaderOption; path: string[] }[] = options.value.map(
(node) => ({ node, path: [node.value] })
)
while (queue.length > 0) {
const { node, path } = queue.shift()!
if (node.children?.length) {
node.children.forEach((child) => {
queue.push({ node: child, path: [...path, child.value as string] })
})
} else {
result.push(path)
}
}
return result
})
watch(value, (val) => {
if (val.length === 0) {
checkAll.value = false
indeterminate.value = false
} else if (val.length === getAllValuePaths.value.length) {
checkAll.value = true
indeterminate.value = false
} else {
indeterminate.value = true
}
})
const handleCheckAll = (val: CheckboxValueType) => {
indeterminate.value = false
value.value = val ? getAllValuePaths.value : []
}
const handleClear = () => {
value.value = []
}
</script>
<style>
.demo {
display: flex;
}
.demo > div {
flex: 1;
text-align: center;
}
.demo > div:not(:last-child) {
border-right: 1px solid var(--el-border-color);
}
.custom-header {
.el-checkbox {
display: flex;
height: unset;
}
}
</style>
Cascader API
Cascader 属性
名称 | 描述 | 类型 | 默认值 |
---|---|---|---|
model-value / v-model | 绑定值 | string / number | — |
options | 选项的数据,`value` 和 `label` 的键可以通过 `CascaderProps` 自定义。 | object | — |
props | 配置选项,请参见下面的 `CascaderProps` 表。 | object | — |
size | 输入框尺寸 | 枚举 | — |
占位符 | 输入框占位文本 | string | — |
disabled | Cascader 是否禁用 | boolean | — |
可清空 | 选中值是否可以清除 | boolean | — |
清除图标 2.11.0 | 自定义清除图标组件 | string / object | CircleClose |
show-all-levels | 是否在输入框中显示选中值的所有级别 | boolean | true |
collapse-tags | 在多选模式下是否折叠标签 | boolean | — |
collapse-tags-tooltip | 当鼠标悬停于折叠标签的文本时,是否显示所有选中的标签。 要使用此属性,`collapse-tags` 属性必须设定为 true | boolean | false |
max-collapse-tags-tooltip-height 2.10.2 | collapse-tags 提示的最大高度。 | string / number | — |
separator | 选项标签分隔符 | string | ' / ' |
filterable | 选项是否可以搜索 | boolean | — |
filter-method | 自定义搜索逻辑,第一个参数是`node`,第二个是`keyword`,需要返回一个布尔值,表示是否命中。 | Function | — |
防抖 | 输入过滤关键词时的防抖延迟,单位为毫秒 | number | 300 |
before-filter | 过滤前的钩子函数,参数为要过滤的值。如果返回 `false` 或返回一个被拒绝的 `Promise`,则过滤将被中止。 | Function | — |
popper-class | Cascader 下拉菜单的自定义类名 | string | '' |
popper-style | Cascader 下拉菜单的自定义样式 | string / object | — |
teleported | cascader 弹出框是否被传送 | boolean | true |
effect 2.10.5 | tooltip 主题,内置主题:`dark` / `light` | enum / string | light |
tag-type | 标签类型 | 枚举 | 信息 |
tag-effect 2.7.8 | 标签效果 | 枚举 | light |
validate-event | 是否触发表单验证 | boolean | true |
max-collapse-tags 2.3.10 | 要显示的最大标签数。要使用此项,`collapse-tags` 必须为 true | number | 1 |
empty-values 2.7.0 | 组件的空值,参见 config-provider | array | — |
value-on-clear 2.7.0 | 清除后的返回值,参见 config-provider | string / number / boolean / Function | — |
persistent 2.7.8 | 当下拉菜单不活动且 `persistent` 为 `false` 时,下拉菜单将被销毁。 | boolean | true |
fallback-placements 2.8.1 | Tooltip 可能的位置列表 popper.js | array | — |
placement 2.8.1 | 下拉框出现的位置 | 枚举 | 下左 |
popper-append-to-body 已弃用 | 是否将 popper 菜单附加到 body。如果 popper 的定位错误,可以尝试将此属性设置为 false。 | boolean | true |
show-checked-strategy 2.10.5 | 多选模式下显示已选中节点的策略。当你希望整洁时使用`parent`。当每个项目都很重要时,使用`child`。 | 枚举 | child |
Cascader 事件
名称 | 描述 | 类型 |
---|---|---|
change | 当绑定值改变时触发 | Function |
expand-change | 当展开选项改变时触发 | Function |
blur | 当 Cascader 失去焦点时触发 | Function |
focus | 当 Cascader 获得焦点时触发 | Function |
clear 2.7.7 | 在可清空的 Select 组件上点击清除图标时触发 | Function |
visible-change | 下拉框出现/隐藏时触发 | Function |
remove-tag | 在多选模式下移除标签时触发 | Function |
Cascader 插槽
名称 | 描述 | 作用域 |
---|---|---|
default | 级联选择器节点的自定义内容,分别是当前节点对象和节点数据。 | object |
empty | 没有匹配选项时的内容。 | — |
prefix 2.9.4 | 作为输入框前缀的内容 | — |
suggestion-item 2.9.5 | 搜索时建议项的自定义内容 | object |
tag 2.10.3 | 自定义标签样式 | object |
header 2.10.5 | 下拉列表顶部的内容 | — |
footer 2.10.5 | 下拉列表底部的内容 | — |
Cascader Exposes
名称 | 描述 | 类型 |
---|---|---|
getCheckedNodes | 获取当前选中节点的数组,(leafOnly) 是否只返回叶子选中节点,默认为`false` | Function |
cascaderPanelRef | cascader 面板 ref | object |
togglePopperVisible 2.2.31 | 切换 popper 的可见类型 | Function |
contentRef | cascader 内容 ref | object |
presentText 2.8.4 | 选中的内容文本 | object |
CascaderPanel API
CascaderPanel 属性
名称 | 描述 | 类型 | 默认值 |
---|---|---|---|
model-value / v-model | 绑定值 | string /number | — |
options | 选项的数据,`value` 和 `label` 的键可以通过 `CascaderProps` 自定义。 | object | — |
props | 配置选项,请参见下面的 `CascaderProps` 表。 | object | — |
CascaderPanel 事件
名称 | 描述 | 类型 |
---|---|---|
change | 当绑定值改变时触发 | Function |
update:modelValue | 当绑定值改变时触发 | Function |
expand-change | 当展开选项改变时触发 | Function |
关闭 | 关闭面板事件,提供给 Cascader 来收起面板的判断。 | Function |
CascaderPanel 插槽
名称 | 描述 | 作用域 |
---|---|---|
default | 级联选择器节点的自定义内容,分别是当前节点对象和节点数据。 | object |
empty 2.8.3 | 面板无数据时的内容。 | — |
CascaderPanel Exposes
名称 | 描述 | 类型 |
---|---|---|
getCheckedNodes | 获取当前选中节点的数组,(leafOnly) 是否只返回叶子选中节点,默认为`false` | Function |
clearCheckedNodes | 清除已选中的节点 | Function |
CascaderProps
属性 | 描述 | 类型 | 默认值 |
---|---|---|---|
expandTrigger | 展开选项的触发模式 | 枚举 | click |
multiple | 是否启用多选 | boolean | false |
checkStrictly | 节点的选中状态是否不影响其父节点和子节点 | boolean | false |
emitPath | 当选中节点改变时,是否发出一个节点路径的数组,如果为 false,只发出节点的值。 | boolean | true |
lazy | 是否动态加载子节点,与`lazyload`属性一起使用 | boolean | false |
lazyLoad | 加载子节点数据的方法,仅当`lazy`为 true 时有效 | Function | — |
value | 指定节点对象的哪个键用作节点的值 | string | value |
label | 指定节点对象的哪个键用作节点的标签 | string | label |
children | 指定节点对象的哪个键用作节点的子节点 | string | children |
disabled | 指定节点对象的哪个键用作节点的禁用 | string | disabled |
leaf | 指定节点对象的哪个键用作节点的叶子字段 | string | leaf |
hoverThreshold | 展开选项的悬停阈值 | number | 500 |
checkOnClickNode 2.10.5 | 点击节点时是否选中或取消选中节点 | boolean | false |
checkOnClickLeaf 2.10.5 | 是否在点击叶子节点(最后的子节点)时选中或取消选中节点。 | boolean | true |
showPrefix 2.10.5 | 是否显示单选框或复选框前缀 | boolean | true |
类型声明
显示声明
type CascaderNodeValue = string | number
type CascaderNodePathValue = CascaderNodeValue[]
type CascaderValue =
| CascaderNodeValue
| CascaderNodePathValue
| (CascaderNodeValue | CascaderNodePathValue)[]
type Resolve = (data: any) => void
type ExpandTrigger = 'click' | 'hover'
type LazyLoad = (node: Node, resolve: Resolve) => void
type isDisabled = (data: CascaderOption, node: Node) => boolean
type isLeaf = (data: CascaderOption, node: Node) => boolean
interface CascaderOption extends Record<string, 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
}
class Node {
readonly uid: number
readonly level: number
readonly value: CascaderNodeValue
readonly label: string
readonly pathNodes: Node[]
readonly pathValues: CascaderNodePathValue
readonly pathLabels: string[]
childrenData: ChildrenData
children: Node[]
text: string
loaded: boolean
/**
* Is it checked
*
* @default false
*/
checked: boolean
/**
* Used to indicate the intermediate state of unchecked and fully checked child nodes
*
* @default false
*/
indeterminate: boolean
/**
* Loading Status
*
* @default false
*/
loading: boolean
// getter
isDisabled: boolean
isLeaf: boolean
valueByOption: CascaderNodeValue | CascaderNodePathValue
// method
appendChild(childData: CascaderOption): Node
calcText(allLevels: boolean, separator: string): string
broadcast(): void
emit(): void
onParentCheck(checked: boolean): void
onChildCheck(): void
setCheckState(checked: boolean): void
doCheck(checked: boolean): void
}
Node as CascaderNode