当前位置:首页 > VUE

vue实现动态菜单

2026-03-10 13:23:33VUE

实现动态菜单的基本思路

动态菜单通常指根据用户权限、角色或后端配置动态生成导航菜单。Vue中可通过以下方式实现:

  1. 定义菜单数据结构 后端返回的菜单数据通常为树形结构,例如:

    [
      {
        "name": "Dashboard",
        "path": "/dashboard",
        "icon": "el-icon-menu",
        "children": []
      },
      {
        "name": "User Management",
        "path": "/user",
        "icon": "el-icon-user",
        "children": [
          {
            "name": "List",
            "path": "/user/list"
          }
        ]
      }
    ]
  2. 存储菜单状态 使用Vuex或Pinia管理菜单状态:

    // store/modules/menu.js
    const state = {
      menus: []
    }
    
    const mutations = {
      SET_MENUS(state, menus) {
        state.menus = menus
      }
    }
    
    const actions = {
      async fetchMenus({ commit }) {
        const res = await api.getMenus()
        commit('SET_MENUS', res.data)
      }
    }

递归组件实现菜单渲染

  1. 创建菜单组件 使用递归组件处理多级菜单:

    <template>
      <div v-for="item in menuData" :key="item.path">
        <el-submenu v-if="item.children" :index="item.path">
          <template #title>
            <i :class="item.icon"></i>
            <span>{{ item.name }}</span>
          </template>
          <menu-item :menu-data="item.children"></menu-item>
        </el-submenu>
        <el-menu-item v-else :index="item.path">
          <i :class="item.icon"></i>
          <span>{{ item.name }}</span>
        </el-menu-item>
      </div>
    </template>
    
    <script>
    export default {
      name: 'MenuItem',
      props: {
        menuData: {
          type: Array,
          required: true
        }
      }
    }
    </script>
  2. 主布局中使用菜单 在布局组件中引入动态菜单:

    vue实现动态菜单

    <template>
      <el-container>
        <el-aside>
          <el-menu router :default-active="$route.path">
            <menu-item :menu-data="menus"></menu-item>
          </el-menu>
        </el-aside>
      </el-container>
    </template>
    
    <script>
    import { mapState } from 'vuex'
    import MenuItem from './MenuItem.vue'
    
    export default {
      components: { MenuItem },
      computed: {
        ...mapState(['menus'])
      },
      created() {
        this.$store.dispatch('fetchMenus')
      }
    }
    </script>

权限控制实现

  1. 路由拦截 结合路由守卫进行权限验证:

    router.beforeEach((to, from, next) => {
      const hasPermission = checkPermission(to.meta.roles)
      if (!hasPermission) {
        next('/403')
      } else {
        next()
      }
    })
  2. 菜单过滤 根据用户角色过滤菜单项:

    function filterMenus(menus, roles) {
      return menus.filter(menu => {
        if (menu.meta && menu.meta.roles) {
          return menu.meta.roles.some(role => roles.includes(role))
        }
        return true
      }).map(menu => {
        if (menu.children) {
          menu.children = filterMenus(menu.children, roles)
        }
        return menu
      })
    }

性能优化建议

  1. 菜单缓存 避免每次路由切换都重新计算菜单:

    vue实现动态菜单

    // 在store中缓存过滤后的菜单
    getters: {
      filteredMenus: (state) => {
        return filterMenus(state.menus, state.user.roles)
      }
    }
  2. 按需加载图标 使用动态图标加载减少初始包大小:

    const iconComponents = {
      'dashboard': () => import('@/icons/Dashboard.vue'),
      'user': () => import('@/icons/User.vue')
    }
    
    // 在组件中使用
    <component :is="iconComponents[item.icon]" />

错误处理方案

  1. 菜单加载失败处理 添加错误状态和重试机制:

    const actions = {
      async fetchMenus({ commit }) {
        try {
          const res = await api.getMenus()
          commit('SET_MENUS', res.data)
        } catch (error) {
          commit('SET_MENU_ERROR', true)
        }
      }
    }
  2. 默认菜单配置 准备静态菜单作为fallback:

    const defaultMenus = [
      {
        name: 'Home',
        path: '/'
      }
    ]

标签: 菜单动态
分享给朋友:

相关文章

vue 实现菜单

vue 实现菜单

Vue 实现菜单的方法 在 Vue 中实现菜单功能可以通过多种方式完成,以下是一些常见的方法: 使用 Vue Router 实现路由菜单 通过 Vue Router 可以轻松实现基于路由的菜单导航。…

css菜单制作

css菜单制作

CSS 菜单制作方法 水平导航菜单 使用 display: inline-block 或 flexbox 可以轻松创建水平导航菜单。以下是一个基本示例: <nav> <ul c…

css制作下拉菜单

css制作下拉菜单

使用纯CSS制作下拉菜单 通过HTML和CSS可以创建无需JavaScript的下拉菜单,主要利用:hover伪类和display属性控制显示隐藏。 HTML结构示例: <div class…

vue动态组件实现

vue动态组件实现

动态组件的基本用法 在Vue中,动态组件通过<component>标签和is属性实现。is属性可以绑定组件名称或组件选项对象,实现动态切换。 <template> <…

vue实现动态弧线

vue实现动态弧线

Vue 实现动态弧线的方法 动态弧线可以通过 SVG 或 Canvas 实现,以下是两种常见的方法: 使用 SVG 实现动态弧线 SVG 的 <path> 元素可以绘制弧线,结合…

纯css制作下拉菜单

纯css制作下拉菜单

使用纯CSS制作下拉菜单 HTML结构需要嵌套列表,外层为触发元素,内层为下拉内容。以下是一个基础结构示例: <div class="dropdown"> <button cl…