当前位置:首页 > 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
分享给朋友:

相关文章

vue实现mvc

vue实现mvc

Vue 实现 MVC 模式 Vue 本身是一个 MVVM(Model-View-ViewModel)框架,但可以通过结构调整实现 MVC(Model-View-Controller)模式。以下是具体实…

vue实现modal

vue实现modal

Vue 实现 Modal 弹窗组件 使用 Vue 实现 Modal 弹窗组件可以通过多种方式,包括原生 Vue 组件、第三方库或自定义指令。以下是几种常见方法: 原生 Vue 组件实现 创建一个基础…

vue tab实现

vue tab实现

Vue Tab 实现方法 使用动态组件实现 Tab 在 Vue 中可以通过动态组件 <component :is="currentTab"> 结合 v-for 和 v-bind 实现 Ta…

实现vue datepicker

实现vue datepicker

安装依赖 使用 vue-datepicker 或第三方库如 v-calendar 或 vue2-datepicker。以 vue2-datepicker 为例: npm install vue2…

vue实现treeselect

vue实现treeselect

Vue TreeSelect 实现方法 使用 Vue 实现 TreeSelect 组件可以通过以下几种方式完成,包括使用现成的第三方库或自行封装组件。 使用第三方库 推荐使用成熟的第三方 TreeS…

vue实现日历

vue实现日历

Vue 实现日历的基本方法 使用 Vue 实现日历可以通过自定义组件或借助第三方库完成。以下是两种常见实现方式: 自定义日历组件 创建基于 Vue 的日历组件需要处理日期计算和渲染逻辑。核心是生成当…