此组件使用的是 element-plus 提供的级联面板
需求
- 由于表格筛选项多占据空间太大,将所有筛选项集合到级联列表里,通过一级列表选择筛选项,二级列表选择筛选值
- 在二级列表可以清除该筛选项
- 在一级列表可以清除所有筛选
实现效果
实现步骤
1 使用el-dropdown结合级联面板组件
<el-dropdown size="default" trigger="hover" :hide-on-click="true">
<el-button size="default"><span class="icon icon-operation">
</span> Filter</el-button>
<template #dropdown>
<el-cascader-panel size="default" ref="cascade" v-model="casFilter" :options="cascadeList" :props="props" @change="getCas"/>
</template>
</el-dropdown>
2 为级联面板添加数据
- 一级菜单的value为搜索字段key
- 二级菜单的value为搜索字段value
cascadeList: [
{
label: "Type",
value: "type",
children: [
{
value: "0",
label: "Account",
},
{
value: "1",
label: "Vilo Inventory",
},
{
value: "2",
label: "Subscribers",
},
{
value: "3",
label: "Wi-Fi Networks",
},
{
value: "4",
label: "Settings",
},
{
value: "",
label:"Clear"
}
],
},
{
label: "Terminal",
value: "terminal",
children: [
{
value: "1",
label: "Web",
},
{
value: "2",
label: "App",
},
{
value: "",
label:"Clear"
}
],
},
{
label: "Clear all",
value:''
}
],
3 设置多选,父子节点不互相关联
- 使用组件提供的props属性,其它属性可以查看官网
props:{
multiple: true,
expandTrigger: 'hover',
checkStrictly:true
},
4 获取级联菜单选择结果
- 取得结果为二维数组,[[一级value,二级value],…]; 循环二维数组,将数据转为对象,{一级value: 二级value, …}
- 当选择二级菜单时,后选择的二级value 应覆盖前面选择的二级value,使用 Object.assign实现覆盖
- 如果二级菜单选择的值为空字符串,删除 key 为 一级value 的属性
- 如果一级菜单的值为空字符串,清空级联列表,结果为空对象
- 当结果为 {} 时,调用表格筛选方法,跳出循环
- 若循环后结果不为 {} ,将对象重新转为二维数组赋值给 v-model, 调用表格筛选方法
getCas(arr) {
let result = {}
if (arr.length > 0) {
for (const [key,value] of arr) {
result = Object.assign(result, { [key]: value })
if (value=="") {
delete result[key]
if (JSON.stringify(result) == '{}') {
this.$refs.cascade.clearCheckedNodes()
this.$nextTick(() => {
this.casFilter = []
})
break;
}
}
if (key == "") {
result = {}
this.$refs.cascade.clearCheckedNodes()
this.$nextTick(() => {
this.casFilter = []
})
break;
}
}
}
if (JSON.stringify(result)!="{}") {
this.casFilter = Object.entries(result)
}
},
5 样式修改
- 一级菜单不需要选择框,直接隐藏
- 二级菜单的方框修改为圆框
- clear 选项不需要选择框,直接隐藏
:deep(div.el-scrollbar.el-cascader-menu:first-child li.el-cascader-node>label.el-checkbox) {
opacity: 0;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node:last-of-type>label.el-checkbox .el-checkbox__input){
width:0;
opacity: 0;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node:last-of-type .el-cascader-node__label){
padding-left: 0;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node .el-checkbox__input .el-checkbox__inner) {
border-radius: 50%;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node .el-checkbox__input.is-checked .el-checkbox__inner) {
border-color: #fff;
}
:deep(div.el-scrollbar.el-cascader-menu li.el-cascader-node .el-checkbox){
width: 80%;
height: 100%;
z-index: 10;
position: absolute;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(1) li.el-cascader-node:not(:last-of-type) .el-checkbox),
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node .el-checkbox.is-checked){
pointer-events: none;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node:not(:last-of-type) .el-cascader-node__label){
margin-left: 10px;
}
:deep(div.el-scrollbar.el-cascader-menu:nth-child(2) li.el-cascader-node .el-checkbox__input .el-checkbox__inner::after){
border: none;
}