当前位置:首页 > VUE

vue动态菜单实现

2026-02-19 04:00:07VUE

Vue 动态菜单实现

数据驱动菜单结构

动态菜单的核心是通过数据驱动渲染。通常从后端接口获取菜单数据,存储为数组或树形结构。例如:

// 示例菜单数据结构
const menuData = [
  {
    id: 1,
    name: "首页",
    path: "/home",
    icon: "el-icon-house",
    children: []
  },
  {
    id: 2,
    name: "系统管理",
    path: "/system",
    icon: "el-icon-setting",
    children: [
      { id: 21, name: "用户管理", path: "/system/user" }
    ]
  }
]

递归组件实现多级菜单

使用递归组件处理无限层级菜单。创建 MenuItem.vue 组件:

<template>
  <el-submenu v-if="item.children" :index="item.path">
    <template #title>
      <i :class="item.icon"></i>
      <span>{{ item.name }}</span>
    </template>
    <menu-item 
      v-for="child in item.children" 
      :key="child.id" 
      :item="child"
    />
  </el-submenu>
  <el-menu-item v-else :index="item.path">
    <i :class="item.icon"></i>
    <span>{{ item.name }}</span>
  </el-menu-item>
</template>

<script>
export default {
  name: 'MenuItem',
  props: {
    item: Object
  }
}
</script>

路由权限控制

结合 Vue Router 实现动态路由添加。在路由守卫中处理权限:

// router/index.js
router.beforeEach(async (to, from, next) => {
  const hasMenu = store.getters.menuList.length > 0
  if (!hasMenu) {
    const menuData = await store.dispatch('getMenuData')
    const routes = generateRoutes(menuData)
    router.addRoutes(routes)
  }
  next()
})

// 动态路由生成函数
function generateRoutes(menuData) {
  return menuData.map(item => ({
    path: item.path,
    component: () => import(`@/views${item.path}.vue`),
    children: item.children ? generateRoutes(item.children) : []
  }))
}

状态管理集成

使用 Vuex 集中管理菜单状态:

vue动态菜单实现

// store/modules/menu.js
export default {
  state: {
    menuList: []
  },
  mutations: {
    SET_MENU(state, payload) {
      state.menuList = payload
    }
  },
  actions: {
    async getMenuData({ commit }) {
      const res = await api.getMenu()
      commit('SET_MENU', res.data)
      return res.data
    }
  }
}

响应式菜单激活

处理菜单激活状态与路由同步:

<!-- MainLayout.vue -->
<el-menu 
  :default-active="$route.path"
  :router="true"
  @select="handleSelect"
>
  <menu-item 
    v-for="item in menuList" 
    :key="item.id" 
    :item="item"
  />
</el-menu>

菜单权限过滤

根据用户角色过滤可见菜单项:

vue动态菜单实现

// utils/auth.js
export function filterMenu(menuData, roles) {
  return menuData.filter(item => {
    if (item.meta?.roles) {
      return item.meta.roles.some(role => roles.includes(role))
    }
    return true
  }).map(item => {
    if (item.children) {
      item.children = filterMenu(item.children, roles)
    }
    return item
  })
}

性能优化建议

对于大型菜单系统,可采用以下优化方案:

  • 菜单数据懒加载:只在展开父菜单时加载子项
  • 使用 keep-alive 缓存高频访问的菜单组件
  • 对菜单数据进行扁平化处理,减少递归深度

典型问题解决方案

处理菜单图标动态加载:

// 创建图标映射
const iconMap = {
  'home': 'el-icon-house',
  'user': 'el-icon-user'
}

// 在组件中使用
<i :class="iconMap[item.iconKey]"></i>

处理外链菜单项:

<el-menu-item 
  v-if="item.isExternal"
  @click="window.open(item.path)"
>
  外链菜单
</el-menu-item>

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

相关文章

纯css制作tab菜单

纯css制作tab菜单

纯CSS制作Tab菜单的方法 使用radio input控制切换 通过<input type="radio">和<label>元素配合实现无JavaScript的Tab切换效果…

纯css制作下拉菜单

纯css制作下拉菜单

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

vue实现悬浮菜单

vue实现悬浮菜单

实现悬浮菜单的基本思路 使用Vue实现悬浮菜单通常需要结合CSS定位和Vue的事件监听。核心是通过v-show或v-if控制菜单显隐,通过鼠标事件触发状态变化。 HTML结构示例 <t…

vue 实现菜单下拉

vue 实现菜单下拉

Vue 实现菜单下拉的方法 使用 v-show 或 v-if 控制显示 通过 Vue 的指令 v-show 或 v-if 可以轻松控制下拉菜单的显示与隐藏。v-show 通过 CSS 的 displa…

vue实现抽屉菜单

vue实现抽屉菜单

Vue 实现抽屉菜单 使用 Vue 过渡和 CSS 实现 通过 Vue 的过渡组件和 CSS 实现抽屉菜单的动画效果。定义一个布尔值控制抽屉的显示和隐藏,利用 CSS 过渡效果实现平滑的滑动。 &l…

vue实现动态换肤

vue实现动态换肤

Vue 动态换肤实现方法 动态换肤是前端开发中常见的需求,Vue 可以通过多种方式实现这一功能。以下是几种常见的实现方法: CSS 变量结合 Vuex 或 Pinia 定义全局 CSS 变量,通过…