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)

}

})

}

但是过滤的不彻底,层级太多,就过滤不了,即使过滤了也还会显示菜单下拉项箭头。

vue 多级菜单数据过滤?
求教大家对于层级太多的菜单怎么才能过滤出来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

回到顶部