vue 多级菜单数据过滤?
el-menu实现无线多层级的菜单数据过滤,菜单显示与不显示是后台可配置的,根据一个定义好的状态字段来显示,status为0不显示,反之显示。
LeftMenuTree.vue组件:
<template> <div>
<template v-for="(item, index) in this.menuData">
<!-- 情况一:有子集的情况 -->
<el-submenu :key="index" :index="String(index + 1)" v-if="item.children && item.children.length > 0">
<template slot="title">
<i :class="[item.icon || 'el-icon-menu']" style="color: #000"></i>
<span slot="title" style="margin-left: 9px">{{item.menuName}}</span>
</template>
<left-menu-tree :menuData="item.children"></left-menu-tree>
</el-submenu>
<!-- 情况二:没子集的情况 -->
<el-menu-item :key="index" v-else-if="item.menuStatus && item.menuStatus == 1" :index="String(index + 1)">
<i :class="[item.icon || 'el-icon-menu']" style="color: #fff"></i>
<span slot="title">{{item.menuName}}</span>
</el-menu-item>
</template>
</div>
</template>
<script>
import { OPENTYPE } from "@/config/constant";
export default {
props: ['menuData'],
name: 'LeftMenuTree',
}
</script>
组件中使用:
<div class="left-menu"> <el-menu
active-text-color="#303133"
class="el-menu-vertical-demo"
text-color="#606266"
@open="handleOpen"
@close="handleClose"
>
<left-menu-tree :menuData="menuList"></left-menu-tree>
</el-menu>
</div>
后端返回的数据结构如下:
const menuList= [ {
menuName: '菜单一',
menuStatus: 1,
children: [
{
menuName: 'ww',
menuStatus: 0,
},
{
menuName: 'rr',
menuStatus: 1,
children: [
{
menuName: 'tt',
status: 1,
children: [
{
menuName: 'ooo',
menuStatus: 0,
},
{
menuName: 'pp',
menuStatus: 1,
children: [
{
menuName: 'ooo',
menuStatus: 0,
},
{
menuName: 'pp',
menuStatus: 0,
},
]
},
]
},
{
menuName: 'rr',
menuStatus: 0,
},
]
},
]
},
{
menuName: '菜单二',
menuStatus: 1,
children: [
{
menuName: 'bb',
menuStatus: 0,
},
{
menuName: 'we',
menuStatus: 0,
},
]
},
{
menuName: '菜单三',
menuStatus: 1,
}
]
这个时候就需要根据menuStatus状态值来显示,于是写了一个方法:
this.menuList.?.map(item => { return {
...item,
children: item.children?.filter(item => item.menuStatus !== 0)
}
})
}
但是过滤的不彻底,层级太多,就过滤不了,即使过滤了也还会显示菜单下拉项箭头。
求教大家对于层级太多的菜单怎么才能过滤出来menuStatus等于1的数据
回答:
function filterMenuData(menuData) { return menuData
.filter(item => item.menuStatus === 1)
.map(item => {
if (item.children) {
return {
...item,
children: filterMenuData(item.children)
};
} else {
return item;
}
});
}
this.menuList = filterMenuData(this.menuList);
回答:
首先,你这个方法写得略有问题,不能过滤深层次的,可以参考下面这一段递归:
const trees = [ {
label: 'l1',
visiblity: true,
children: [
{
label: 'l1-1',
visiblity: true,
children: [
{
label: 'l1-1-1',
visiblity: true,
children: [
{
label: 'l1-1-1-1',
visiblity: true,
children: [
{
label: 'l1-1-1-1-1',
visiblity: true,
children: [
{
label: 'l1-1-1-1-1-1',
visiblity: false
},
{
label: 'l1-1-1-1-1-2',
visiblity: true
}
]
}
]
}
]
}
]
}
]
},
{
label: 'l2',
visiblity: true,
children: [
{
label: 'l2-1',
visiblity: true,
children: [
{
label: 'l2-1-1',
visiblity: true,
children: [
{
label: 'l2-1-1-1',
visiblity: false,
children: [
{
label: 'l2-1-1-1-1',
visiblity: true,
children: [
{
label: 'l2-1-1-1-1-1',
visiblity: false
},
{
label: 'l2-1-1-1-1-2',
visiblity: true
}
]
}
]
}
]
}
]
}
]
}
];
type TTreeItem = {
label: string;
visiblity: boolean;
children?: TTreeItem[];
};
function filterTrees(data: TTreeItem[]) {
return data.filter(x => {
if (x.children) {
x.children = filterTrees(x.children);
!x.children.length && delete x.children;
}
return !!x.visiblity;
});
}
console.log(filterTrees(trees));
/*
[{"label":"l1","visiblity":true,"children":[{"label":"l1-1","visiblity":true,"children":[{"label":"l1-1-1","visiblity":true,"children":[{"label":"l1-1-1-1","visiblity":true,"children":[{"label":"l1-1-1-1-1","visiblity":true,"children":[{"label":"l1-1-1-1-1-2","visiblity":true}]}]}]}]}]},{"label":"l2","visiblity":true,"children":[{"label":"l2-1","visiblity":true,"children":[{"label":"l2-1-1","visiblity":true}]}]}]
*/
第二,可以与 web 协商,status
作为接口入参,想要什么数据,接口加层过滤更合适些
以上是 vue 多级菜单数据过滤? 的全部内容, 来源链接: utcz.com/p/934664.html