el-menu + el-badge 菜单加红点标识el-badge
main.js引入全局组件/mixins全局混入
el-menu封装
一、el-menu组件
menu/index.vue
重点:定义 ref="menu"
,切换路由时调用 refreshs()
更新组件
<template>
<el-menu :unique-opened="true" :default-active="this.$store.state.menuData.menuActive" class="el-menu-vertical-demo" :background-color="backgroundColor" :text-color="textColor" :active-text-color="activeTextColor">
<subMenu ref="menu" :menuList="sideNavMenu" :key="Math.random()"></subMenu>
</el-menu>
</template>
<script>
export default {
name: "index",
data() {
return {
backgroundColor: "#EAEEF6",
textColor: "#3F434E",
activeTextColor: "#2A60CC",
// 菜单列表
sideNavMenu: []
}
},
mounted() { },
methods: {
async refreshs() {
await this.getMenuBadge()
this.$refs.menu.refreshs();
}
},
watch: {
$route(to, from) {
this.refreshs()
},
},
created() { },
}
</script>
menu/submenu.vue
重点:定义ref="subMenu"
,调用 refreshs()
更新组件,el-badge
展示标识未处理数据数量
<el-badge v-if="!!list.badgeNum" :value="list.badgeNum" :max="99"> </el-badge>
<template>
<div>
<div v-for="(list,index) in this.menuList" :key="index">
<el-submenu v-if="!!list.children" :key="list.id" :index="String(list.id)">
<template slot="title">
<i class="menu_icon" :class="list.icon"></i>
<span slot="title">{{ list.name}}</span>
<el-badge v-if="!!list.badgeNum" :value="list.badgeNum" :max="99"> </el-badge>
<!-- <el-badge v-if="list.showBadge" value="new"> </el-badge> -->
</template>
<subMenu ref="subMenu" :menuList="list.children"></subMenu>
</el-submenu>
<el-menu-item v-else :index="list.path">
<router-link :target="targeLink(list.path)?'_blank':''" :to="list.path">
<i class="menu_icon" :class="list.icon"></i>
<span>{{list.name}}</span>
<el-badge v-if="!!list.badgeNum" :value="list.badgeNum" :max="99"> </el-badge>
</router-link>
</el-menu-item>
</div>
</div>
</template>
<script>
export default {
name: "submenu",
data() {
return {}
},
props: {
menuList: Array
},
mounted() { },
methods: {
targeLink(path) {
if (path === '/aboutUs') {
return true
} else {
return false
}
},
refreshs() {
this.$forceUpdate()
if (this.$refs.subMenu) {
this.$refs.subMenu.forEach(item => {
item.refreshs()
})
}
},
},
watch: {},
created() { },
}
</script>
二、获取/更新菜单红点标识
调用 getMenuBadge()
获取/更新待办数据(红点显示数据)
api.js
import { getOneOrAllData } from '@/common/js/http'
// 菜单接口
export const getMenuListApi = p => getOneOrAllData('/getMenuListApi', p)
// 菜单角标数据接口
export const getMenuBadgeApi = {
getMenuHomeBadgeApi: p => getOneOrAllData('/getMenuHomeBadgeApi ', p),//首页待办数量
getMenuAboutBadgeApi: p => getOneOrAllData('/globalApi/home/examineConsumptionCount', p),//关于页核待办数量
};
mixins
引入全局 public.js
文件
data() {
return {
// 登录人筛选后的菜单红点标识
hasBadgeMenu: null,
// 菜单红点标识定义
badgeItem: {
// 第一个参数是 hasBadgeMenu 下 obj 下标(pObjOrder)
// 第二个参数是 obj 中 child 中的 obj 下标(cObjOrder)
// 第三个参数是调用的接口
'/basicDataReview': [0, 0, 'getMenuHomeBadgeApi'], // 首页待办数量
'/publicDataReview': [0, 1, 'getMenuAboutBadgeApi'], // 关于页核待办数量
},
}
},
// 有权限的菜单
getMenuList() {
// 调接口
getMenuListApi().then(async res => {
// 保存菜单数据到vuex
this.$store.commit("menuData/change_sideNavMenu", res.data);
// 菜单红点标识
await this.getMenuBadge()
// 跳转路由
this.jumpRouter(this.$store.state.menuData.sideNavMenu)
})
},
// 更新菜单红点标识
async getMenuBadge() {
// 获取vuex中的菜单
let sideMenu = this.$store.state.menuData.sideNavMenu
// hasBadgeMenu 数据格式
// hasBadgeMenu = [
// {
// item:{ },
// child:[
// { item: {}, api: 'getMenuHomeBadgeApi' },
// { item: {}, api: 'getMenuAboutBadgeApi' },
// ]
// }
// ]
// 过滤登录人所需菜单红点标识
if (!this.hasBadgeMenu) {
this.hasBadgeMenu = []
sideMenu.forEach(item => {
if (!!item.children) {
item.children.forEach(cItem => {
for (var key of Object.keys(this.badgeItem)) {
if (cItem.path === key) {
let pObjOrder = this.badgeItem[key][0]
if (!this.hasBadgeMenu[pObjOrder]) {
this.hasBadgeMenu[pObjOrder] = {}
}
if (!this.hasBadgeMenu[pObjOrder].child) {
this.hasBadgeMenu[pObjOrder].child = []
}
let cObjOrder = this.badgeItem[key][1]
if (!this.hasBadgeMenu[pObjOrder].child[cObjOrder]) {
this.hasBadgeMenu[pObjOrder].child[cObjOrder] = {}
}
this.hasBadgeMenu[pObjOrder].child[cObjOrder].item = cItem
this.hasBadgeMenu[pObjOrder].child[cObjOrder].api = this.badgeItem[key][2]
this.hasBadgeMenu[pObjOrder].item = item
}
}
})
}
else { }
})
}
// 调用红点信息接口
for (let i in this.hasBadgeMenu) {
if (this.hasBadgeMenu[i]) {
for (let j in this.hasBadgeMenu[i].child)
if (this.hasBadgeMenu[i].child[j]) {
if (getMenuBadgeApi[this.hasBadgeMenu[i].child[j].api]) {
await getMenuBadgeApi[this.hasBadgeMenu[i].child[j].api]().then(res => {
this.hasBadgeMenu[i].child[j].item.badgeNum = res.data
})
} else {
console.error('接口未定义');
}
}
}
}
// 判断父级标识
for (let j in this.hasBadgeMenu) {
// this.hasBadgeMenu[j].item.showBadge = false;
this.hasBadgeMenu[j].item.badgeNum = 0;
for (let i in this.hasBadgeMenu[j].child) {
if (!!this.hasBadgeMenu[j].child[i].item.badgeNum) {
// this.hasBadgeMenu[j].item.showBadge = true;
this.hasBadgeMenu[j].item.badgeNum += this.hasBadgeMenu[j].child[i].item.badgeNum
break
}
}
}
this.$store.commit("menuData/change_sideNavMenu", sideMenu);
},
// 跳转路由
jumpRouter(menuList) {
// 默认登录home页
for (let i in menuList) {
if (menuList[i].path === '/home') {
this.$router.push({ path: menuList[i].path })
break
} else {
this.$router.push({ path: menuList[0].path })
}
}
},