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 })
    }
  }
},

相关推荐

  1. el-menu + el-badge 菜单标识el-badge

    2024-03-14 16:14:02       22 阅读
  2. el-table击每一行背景颜色

    2024-03-14 16:14:02       30 阅读
  3. el-tree实现懒

    2024-03-14 16:14:02       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-14 16:14:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-14 16:14:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-14 16:14:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-14 16:14:02       18 阅读

热门阅读

  1. 精读《寻找框架设计的平衡点》

    2024-03-14 16:14:02       19 阅读
  2. SpringBoot有哪些优缺点呢

    2024-03-14 16:14:02       17 阅读
  3. Compound Words(UVA 10391)

    2024-03-14 16:14:02       22 阅读
  4. ARM 汇编指令:(六) B 跳转指令

    2024-03-14 16:14:02       23 阅读
  5. Rust 的 Arc<Mutex<T>> 的用法示例源代码

    2024-03-14 16:14:02       23 阅读
  6. PHP使用 enqueue/amqp-lib拓展实现rabbitmq任务处理

    2024-03-14 16:14:02       19 阅读
  7. 【笔记】学习Android.mk(二)

    2024-03-14 16:14:02       19 阅读
  8. 国内下载gradle-xx-bin/all.zip 的腾讯镜像

    2024-03-14 16:14:02       23 阅读