Cascader 级联器
示例
尺寸
可供选用的尺寸 ui
属性值:xs
/ s
/ m
/ l
。
<template>
<div class="cascader-wrap">
<veui-cascader
v-model="value"
class="cascader"
ui="l"
:options="options"
/>
<veui-cascader
v-model="value"
class="cascader"
:options="options"
/>
<veui-cascader
v-model="value"
class="cascader"
ui="s"
:options="options"
/>
<veui-cascader
v-model="value"
class="cascader"
ui="xs"
:options="options"
/>
</div>
</template>
<script>
import { Cascader } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader
},
data () {
return {
value: null,
options
}
}
}
</script>
<style lang="less" scoped>
.cascader-wrap {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.cascader + .cascader {
margin-top: 12px;
}
</style>
内联模式
使用 inline
属性来开启内联模式。
<template>
<article>
<veui-cascader
v-model="value"
searchable
inline
:options="options"
/>
</article>
</template>
<script>
import { Cascader } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader
},
data () {
return {
value: null,
options
}
}
}
</script>
搜索选项
使用 searchable
属性来开启选项搜索。
<template>
<article>
<veui-cascader
v-model="value"
searchable
:options="options"
/>
</article>
</template>
<script>
import { Cascader } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader
},
data () {
return {
value: null,
options
}
}
}
</script>
多选
使用 multiple
属性来开启多选模式。
<template>
<article>
<section class="cascader-config">
<veui-checkbox
v-model="clearable2"
ui="s"
>
Clearable
</veui-checkbox>
<veui-checkbox
v-model="showSelectAll2"
ui="s"
>
ShowSelectAll
</veui-checkbox>
<veui-radio
v-model="trigger2"
ui="s"
value="click"
name="columnTrigger2"
>
click to expand
</veui-radio>
<veui-radio
v-model="trigger2"
ui="s"
value="hover"
name="columnTrigger2"
>
hover to expand
</veui-radio>
<label>
Max:
<veui-number-input
v-model="max2"
class="input"
ui="s"
/>
</label>
<label>
columnWidth:
<veui-input
v-model="columnWidth2"
class="input"
ui="s"
/>
</label>
</section>
<veui-cascader
v-model="value2"
class="mt-3p"
:options="options"
:searchable="searchable2"
:column-trigger="trigger2"
:clearable="clearable2"
:inline="inline2"
:show-select-all="showSelectAll2"
:max="max2"
:column-width="getRealColumnWidth(columnWidth2)"
multiple
/>
</article>
</template>
<script>
import { Cascader, Checkbox, Radio, NumberInput, Input } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader,
'veui-checkbox': Checkbox,
'veui-radio': Radio,
'veui-number-input': NumberInput,
'veui-input': Input
},
data () {
return {
value2: null,
searchable2: true,
trigger2: 'click',
clearable2: true,
inline2: false,
columnWidth2: '',
showSelectAll2: false,
max2: null,
options
}
},
methods: {
getRealColumnWidth (val) {
if (val && !isNaN(+val)) {
return `${+val}px`
}
return val
}
}
}
</script>
<style lang="less" scoped>
.cascader-config {
display: flex;
align-items: center;
height: 32px;
& > * {
margin-right: 8px;
font-size: 12px;
}
.input {
width: 80px;
}
}
.mt-3p {
margin-top: 12px;
}
</style>
选择模式
使用 select-mode
属性来控制在单选模式下哪些项目可以被选中。
<template>
<article>
<section>
<veui-radio-group
v-model="selectMode"
class="group"
:items="selectModes"
/>
<veui-cascader
:select-mode="selectMode"
:options="options"
/>
</section>
</article>
</template>
<script>
import { Cascader, RadioGroup } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader,
'veui-radio-group': RadioGroup
},
data () {
return {
selectMode: 'any',
selectModes: [
{ label: 'any', value: 'any' },
{ label: 'leaf-only', value: 'leaf-only' }
],
options
}
}
}
</script>
<style lang="less" scoped>
.group {
margin-bottom: 20px;
}
</style>
子项展开时机
使用 column-trigger
属性来控制下拉面板中下级的展开时机。
<template>
<article>
<section>
<veui-radio-group
v-model="trigger"
class="group"
:items="triggers"
/>
<veui-cascader
:column-trigger="trigger"
:options="options"
/>
</section>
</article>
</template>
<script>
import { Cascader, RadioGroup } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader,
'veui-radio-group': RadioGroup
},
data () {
return {
trigger: 'click',
triggers: [
{ label: 'click', value: 'click' },
{ label: 'hover', value: 'hover' }
],
options
}
}
}
</script>
<style lang="less" scoped>
.group {
margin-bottom: 20px;
}
</style>
渲染选中值
使用 value-display
属性来控制选中值如何展示。
<template>
<article>
<section>
<veui-radio-group
v-model="valueDisplay"
class="group"
:items="valueDisplays"
/>
<veui-cascader
:value-display="valueDisplay"
:options="options"
/>
</section>
</article>
</template>
<script>
import { Cascader, RadioGroup } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '威海',
value: '威海'
},
{
label: '滨州',
value: '滨州'
},
{
label: '临沂',
value: '临沂'
},
{
label: '东营',
value: '东营'
},
{
label: '济南',
value: '济南'
}
]
},
{
label: '山东',
value: '山东',
options: [
{
label: '菏泽',
value: '菏泽',
options: [
{
label: '菏泽1',
value: '菏泽1'
}
]
},
{
label: '潍坊',
value: '潍坊',
options: [
{
label: '潍坊1',
value: '潍坊1'
}
]
},
{
label: '泰山',
value: '泰山'
},
{
label: '烟台',
value: '烟台'
},
{
label: '华山',
value: '华山'
},
{
label: '衡山',
value: '衡山'
},
{
label: '嵩山',
value: '嵩山'
},
{
label: '恒山',
value: '恒山'
},
{
label: '大雪山',
value: '大雪山'
}
]
},
{
label: '上海',
value: '上海',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
export default {
components: {
'veui-cascader': Cascader,
'veui-radio-group': RadioGroup
},
data () {
return {
valueDisplay: 'simple',
valueDisplays: [
{ label: 'simple', value: 'simple' },
{ label: 'complete', value: 'complete' }
],
options
}
}
}
</script>
<style lang="less" scoped>
.group {
margin-bottom: 20px;
}
</style>
数据项懒加载
配合使用 load
属性和数据项中 lazy
属性来实现数据懒加载。
<template>
<div>
<veui-cascader
v-model="value"
:options="options"
multiple
:load="load"
/>
</div>
</template>
<script>
import { Cascader } from 'veui'
const options = [
{
label: '浙江',
value: '浙江',
options: [
{
label: '杭州',
value: '杭州'
},
{
label: '宁波',
value: '宁波'
},
{
label: '温州',
value: '温州'
},
{
label: '舟山',
value: '舟山'
},
{
label: '绍兴',
value: '绍兴'
}
]
},
{
label: '上海',
value: '上海',
lazy: true
},
{
label: '重庆',
value: '重庆',
disabled: true
},
{
label: '北京',
value: '北京'
},
{
label: '海外',
value: '海外',
disabled: true,
options: [
{
label: '日本',
value: '日本'
}
]
}
]
const pudongChildren = [
{
label: '张江',
value: '张江'
},
{
label: '北蔡',
value: '北蔡'
}
]
const loadShanghai = (descendants) => [
{
label: '浦东新区',
value: '浦东新区',
lazy: true,
...(descendants ? { options: pudongChildren } : null)
},
{
label: '闵行',
value: '闵行',
options: [
{
label: '莘庄',
value: '莘庄'
},
{
label: '颛桥',
value: '颛桥'
}
]
},
{
label: '宝山',
value: '宝山',
// load no data
...(descendants ? null : { lazy: true })
},
{
label: '徐汇',
value: '徐汇',
disabled: true
}
]
export default {
components: {
'veui-cascader': Cascader
},
data () {
return {
value: null,
options
}
},
methods: {
load: ({ parent, scope }) => {
return new Promise((resolve) => {
setTimeout(() => {
let descendants
switch (scope) {
case 'children':
descendants = false
break
case 'descendants':
descendants = true
break
default:
console.warn('Not supported.')
resolve()
return
}
resolve(
parent
? {
浦东新区: pudongChildren,
上海: loadShanghai(descendants)
}[parent.value]
: undefined
)
}, 1000)
})
}
}
}
</script>
API
属性
名称 | 类型 | 默认值 | 描述 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ui | string | - | 预设样式。
| ||||||||||||||||||
options | Array<Object> | - | 选项列表,项目的类型为
| ||||||||||||||||||
value | Array<*>|* | - |
已选值。 | ||||||||||||||||||
multiple | boolean | false | 是否允许多选。 | ||||||||||||||||||
inline | boolean | false | 下拉面板是否以内联模式展示(展开选项将拆分面板而非向外扩展)。 | ||||||||||||||||||
max | number | - | 多选时允许选择的项目上限。 | ||||||||||||||||||
placeholder | string | cascader.placeholder | 未选择时的占位文本。 | ||||||||||||||||||
clearable | boolean | false | 是否可以清除已选内容。 | ||||||||||||||||||
searchable | boolean | false | 是否允许搜索选项。 | ||||||||||||||||||
expanded | boolean | false |
下拉菜单是否展开。 | ||||||||||||||||||
column-trigger | 'hover' | 'click' | 'click' | 下拉面板中下级的展开时机。
| ||||||||||||||||||
select-mode | 'leaf-only' | 'any' | 'any' | 在单选模式下控制哪些项目可以选中。
| ||||||||||||||||||
column-width | number | string | - | 当下拉面板中有多列时,统一控制除了最后一列之外的列宽度。 当该值是数值或者能转换成数值时,会当成像素值。 | ||||||||||||||||||
show-select-all | boolean | false | 在多选模式下是否有全选按钮。 | ||||||||||||||||||
value-display | 'complete' | 'simple' | 'simple' | 控制选中值如何展示。
| ||||||||||||||||||
merge-checked | string | keep-all | 选中值的合并策略。当某个节点下的所有子节点都被选中时,可以选择只保留父节点、只保留子节点或都保留。
| ||||||||||||||||||
include-indeterminate | boolean | false | 是否将半选状态的节点加入已选项。datasource 节点中的非叶子节点若有部分子孙节点被选中,则为半选状态。 | ||||||||||||||||||
disabled | boolean | false | 是否为禁用状态。 | ||||||||||||||||||
readonly | boolean | false | 是否为只读状态。 | ||||||||||||||||||
overlay-class | string | Array | Object | - | 参考 Overlay 组件的 overlay-class 属性。 | ||||||||||||||||||
overlay-style | string | Array | Object | - | 参考 Overlay 组件的 overlay-style 属性。 | ||||||||||||||||||
match | (item, keyword, { ancestors }) => boolean | Array<[number, number]> | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 Autocomplete 。 | ||||||||||||||||||
filter | (item, keyword, { ancestors, offsets }) => boolean | - | 支持自定义搜索命中逻辑,参考 Autocomplete 。 | ||||||||||||||||||
load | Function | - | 数据项懒加载,配合数据项上
|
插槽
名称 | 描述 | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
trigger | 整个下拉触发区域。 默认内容:下拉按钮。
| ||||||||||||||||||||||||||||||
pane | 下拉面板中的内容插槽。插槽参数同 trigger 插槽。 | ||||||||||||||||||||||||||||||
before | 选项列表前的内容。无默认内容。插槽参数同 trigger 插槽。 | ||||||||||||||||||||||||||||||
after | 选项列表后的内容。无默认内容。插槽参数同 trigger 插槽。 | ||||||||||||||||||||||||||||||
column-before | 下拉面板中每列前的区域。无默认内容。
| ||||||||||||||||||||||||||||||
column-after | 下拉面板中每列后的区域。无默认内容。插槽参数同 column-before 插槽。 | ||||||||||||||||||||||||||||||
label | 下拉按钮文本区域。 默认内容:已选项对应的
另外,当前选项数据中除了上面描述的字段之外的其它字段也会自动通过 | ||||||||||||||||||||||||||||||
option-label | 下拉选项(不带 默认内容:选项的
| ||||||||||||||||||||||||||||||
option | 可供选择的下拉选项的整个区域。 默认内容: 插槽参数同 | ||||||||||||||||||||||||||||||
selected | 选中值渲染区域。 默认内容:单选时渲染选中项目的文本;多选时将每个选中项目的标签渲染成
|
事件
名称 | 描述 |
---|---|
input | 输入搜索关键词时触发。回调参数为 (value: string) ,value 为输入框的 value 值。 |
select |
选中状态变化后触发,回调参数为 |
afteropen | 下拉打开后触发。 |
afterclose | 下拉关闭后触发。 |
全局配置
配置项 | 类型 | 默认值 | 描述 |
---|---|---|---|
cascader.placeholder | string | @@cascader.placeholder | 未选择时的占位内容。 |
图标
名称 | 描述 |
---|---|
expand | 展开下拉。 |
collapse | 收起下拉。 |
clear | 清除。 |
separator | 分隔符。 |
自定义样式
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
--dls-dropdown-max-display-items | <integer> | 8 | 下拉选项同时显示的最大项目数,下拉框的最大高度将由此计算得出。 |