Cascader级联选择器
约 719 字大约 2 分钟
2025-02-06
基础用法
通过将`type`属性的值指定为`cascader`,同时配置`dicData`为字典值,通过`expandTrigger`可以定义展开子级菜单的触发方式,默认为`hover`
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}]
}]
}];
const option = ref({
column: [{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dicData
}, {
label: '级联',
prop: 'cascader1',
type: 'cascader',
expandTrigger: 'click',
dicData: dicData
}]
});
</script>默认值
`value`属性可以提供一个初始化的默认值
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
value: ['zhinan', 'shejiyuanze', 'yizhi'],
dicData: dicData
}
]
});
</script>多选
`multiple`为`true`在开启多选模式后,默认情况下会展示所有已选中的选项的Tag,你可以使用`collapseTags`为`true`来折叠Tag,你也可以设置`collapseTags`属性将它们合并为一段文字,同时配合`maxCollapseTags`最大显示个数和`collapseTagsTooltip`是否折叠提示
<template>
<tvue-form v-model="form"
:option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dic = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const form = ref({
cascader: [["zhinan", "shejiyuanze", "yizhi"], ["zhinan", "shejiyuanze", "fankui"]]
});
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dic,
multiple: true
},
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dic,
collapseTags: true,
maxCollapseTags: 3,
collapseTagsTooltip: true,
multiple: true
}
]
});
</script>禁用状态
通过`disabled`属性指定是否禁用
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{
value: 'yizhi',
label: '一致'
},
{
value: 'fankui',
label: '反馈'
}
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dicData,
disabled: true
}
]
});
</script>禁用选项
返回的字典中数据配置`disabled`属性指定是否禁用
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
disabled: true,
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}]
}]
}];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dicData
}
]
});
</script>下拉框样式
.popperClass .el-cascader-node{
background-color: rgba(0,0,0,.2);
}`popperClass`属性配置样式的`class`名字
<template>
<tvue-form :option="option"
v-model="form"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const form = ref({});
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
popperClass: 'popperClass',
dicData: dicData
}
]
});
</script>网络字典
更多用法参考表单数据字典
配置`dicUrl`指定后台接口的地址
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const option = ref({
column: [{
label: '级联框',
prop: 'cascader',
type: 'cascader',
props: {
label: 'name',
value: 'code'
},
dicUrl: 'https://cli.avuejs.com/api/area/getProvince'
}]
});
</script>仅显示最后一级
可以仅在输入框中显示选中项最后一级的标签,而不是选中项所在的完整路径。
属性`showAllLevels`定义了是否显示完整的路径,将其赋值为`false`则仅显示最后一级
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dicData,
showAllLevels: false
}
]
});
</script>选中单节点
在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置
false,则只返回该节点的值
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dic = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{
value: 'yizhi',
label: '一致'
},
{
value: 'fankui',
label: '反馈'
}
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
emitPath: false,
dicData: dic
}
]
});
</script>任意一级
在单选模式下,你只能选择叶子节点;而在多选模式下,勾选父节点真正选中的都是叶子节点。启用该功能后,可让父子节点取消关联,选择任意一级选项。
可通过`checkStrictly` 为`true` 来设置父子节点取消选中关联,从而达到选择任意一级选项的目的
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dic = [{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}]
}]
}];
const option = ref({
column: [{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dic,
checkStrictly: true
}]
});
</script>搜索
可以快捷地搜索选项并选择。
将`filterable`赋值为true即可打开搜索功能,默认会匹配节点的label或所有父节点的label(由`showAllLevels`决定)中包含输入值的选项
<template>
<tvue-form :option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dicData = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dicData,
showAllLevels: false
}
]
});
</script>自定义模版
配置`props`名称加`Type`卡槽开启即可自定义下拉框的内容
<template>
<tvue-form :option="option">
<template #cascader-type="{ node, data }">
<span>{{ (data || {}).label }}</span>
<span v-if="!node.isLeaf"> ({{ ((data || {}).children || []).length }}) </span>
</template>
</tvue-form>
</template>
<script setup>
import { ref } from 'vue';
const dic = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
dicData: dic
}
]
});
</script>懒加载
<template>
<tvue-form v-model="form"
:option="option"></tvue-form>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const baseUrl = 'https://cli.avuejs.com/api/area';
const dic = [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' }
]
}
]
}
];
const form = ref({
cascader: ["110000", "110100", "110101"]
});
const option = ref({
column: [
{
label: '级联',
prop: 'cascader',
type: 'cascader',
props: {
label: 'name',
value: 'code'
},
lazy: true,
lazyLoad (node, resolve) {
const stopLevel = 2;
const level = node.level;
const data = node.data || {};
const code = data.code;
let list = [];
const callback = () => {
resolve((list || []).map(ele => ({
...ele,
leaf: level >= stopLevel
})));
};
if (level === 0) {
axios.get(`${baseUrl}/getProvince`).then(res => {
list = res.data;
callback();
});
} else if (level === 1) {
axios.get(`${baseUrl}/getCity/${code}`).then(res => {
list = res.data;
callback();
});
} else if (level === 2) {
axios.get(`${baseUrl}/getArea/${code}`).then(res => {
list = res.data;
callback();
});
} else {
callback();
}
}
}
]
});
</script>