当前位置:首页 > VUE

vue实现菜单调用

2026-01-12 00:50:35VUE

Vue 实现动态菜单调用的方法

使用路由配置生成菜单

在 Vue 项目中,可以通过路由配置自动生成菜单结构。路由配置通常包含 pathnamemeta 等信息,这些信息可用于构建菜单项。

// router/index.js
const routes = [
  {
    path: '/dashboard',
    name: 'Dashboard',
    meta: { title: '控制台', icon: 'el-icon-s-home' }
  },
  {
    path: '/user',
    name: 'User',
    meta: { title: '用户管理', icon: 'el-icon-user' },
    children: [
      {
        path: 'list',
        name: 'UserList',
        meta: { title: '用户列表' }
      }
    ]
  }
]

在组件中遍历路由配置生成菜单:

<template>
  <el-menu :router="true">
    <template v-for="route in $router.options.routes">
      <el-submenu 
        v-if="route.children" 
        :index="route.path"
        :key="route.path"
      >
        <template #title>
          <i :class="route.meta.icon"></i>
          <span>{{ route.meta.title }}</span>
        </template>
        <el-menu-item 
          v-for="child in route.children" 
          :key="child.path" 
          :index="child.path"
        >
          {{ child.meta.title }}
        </el-menu-item>
      </el-submenu>
      <el-menu-item 
        v-else 
        :index="route.path" 
        :key="route.path"
      >
        <i :class="route.meta.icon"></i>
        <span>{{ route.meta.title }}</span>
      </el-menu-item>
    </template>
  </el-menu>
</template>

从后端API获取菜单数据

实际项目中,菜单数据通常由后端根据用户权限返回。可以创建 menuService 获取数据:

// services/menuService.js
export const getMenus = () => {
  return axios.get('/api/menus')
}

在组件中调用并渲染:

vue实现菜单调用

<script>
import { getMenus } from '@/services/menuService'

export default {
  data() {
    return {
      menus: []
    }
  },
  async created() {
    this.menus = await getMenus()
  }
}
</script>

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

递归组件实现多级菜单

对于深层级菜单,可以使用递归组件:

<template>
  <el-menu>
    <menu-item 
      v-for="item in menus" 
      :key="item.id" 
      :item="item"
    />
  </el-menu>
</template>

<script>
import MenuItem from './MenuItem.vue'

export default {
  components: { MenuItem },
  data() {
    return {
      menus: [
        {
          id: 1,
          title: '系统管理',
          children: [
            {
              id: 2,
              title: '用户管理',
              children: [
                { id: 3, title: '添加用户', path: '/user/add' }
              ]
            }
          ]
        }
      ]
    }
  }
}
</script>

MenuItem.vue 组件:

vue实现菜单调用

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

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

权限控制实现

结合权限系统,可以过滤用户可见的菜单项:

// utils/auth.js
export const filterMenus = (menus, permissions) => {
  return menus.filter(menu => {
    if (menu.permission && !permissions.includes(menu.permission)) {
      return false
    }
    if (menu.children) {
      menu.children = filterMenus(menu.children, permissions)
    }
    return true
  })
}

在组件中使用:

<script>
import { filterMenus } from '@/utils/auth'
import { getMenus } from '@/services/menuService'

export default {
  computed: {
    permissions() {
      return this.$store.state.user.permissions
    }
  },
  async created() {
    const allMenus = await getMenus()
    this.menus = filterMenus(allMenus, this.permissions)
  }
}
</script>

动态路由与菜单结合

对于权限系统,可能需要动态添加路由:

// router/index.js
export function generateRoutes(menus) {
  const routes = []
  menus.forEach(menu => {
    const route = {
      path: menu.path,
      name: menu.name,
      component: () => import(`@/views/${menu.component}`)
    }
    if (menu.children) {
      route.children = generateRoutes(menu.children)
    }
    routes.push(route)
  })
  return routes
}

// 在登录后调用
const newRoutes = generateRoutes(menusFromBackend)
router.addRoutes(newRoutes)

标签: 菜单vue
分享给朋友:

相关文章

eventbus vue实现

eventbus vue实现

EventBus 实现原理 EventBus 是一种发布/订阅模式,用于 Vue 组件间的通信。核心是通过一个中央事件总线管理事件监听和触发。 创建 EventBus 在 Vue 项目中创建一个独立…

vue实现高亮

vue实现高亮

Vue 实现文本高亮的方法 在 Vue 中实现文本高亮可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 v-html 指令 通过 v-html 指令可以动态插入 HTML 内容,将需要高…

实现简易vue

实现简易vue

实现简易 Vue 的核心思路 Vue 的核心功能包括数据响应式、模板编译和虚拟 DOM。以下是一个简易实现方案,涵盖核心功能模块。 数据响应式系统 通过 Object.defineProperty…

vue原理实现

vue原理实现

Vue 原理实现的核心机制 Vue.js 的核心原理基于响应式系统、虚拟 DOM 和模板编译。以下是其核心实现机制的分解: 响应式系统 Vue 使用 Object.defineProperty(Vu…

vue实现tap

vue实现tap

Vue 实现 Tap 事件 在移动端开发中,Tap 事件比 Click 事件更常用,因为 Click 事件有 300ms 延迟。以下是几种在 Vue 中实现 Tap 事件的方法。 使用第三方库 安装…

vue事件实现

vue事件实现

Vue 事件实现方法 在Vue中,事件处理是通过v-on指令或@简写来实现的。以下是几种常见的事件处理方式: 使用v-on指令绑定事件 <button v-on:click="handleC…