当前位置:首页 > VUE

vue实现menu

2026-01-13 02:36:35VUE

Vue 实现 Menu 组件

基础 Menu 实现

使用 Vue 3 的 Composition API 可以快速实现一个基础的 Menu 组件。以下是一个简单的实现示例:

<template>
  <div class="menu">
    <div 
      v-for="item in items" 
      :key="item.id"
      class="menu-item"
      @click="selectItem(item)"
    >
      {{ item.label }}
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const props = defineProps({
  items: {
    type: Array,
    required: true,
    default: () => []
  }
});

const emit = defineEmits(['select']);

const selectItem = (item) => {
  emit('select', item);
};
</script>

<style scoped>
.menu {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.menu-item {
  padding: 8px 12px;
  cursor: pointer;
  border-radius: 4px;
}

.menu-item:hover {
  background: #f5f5f5;
}
</style>

嵌套子菜单

实现带子菜单的 Menu 组件需要递归组件技术:

<template>
  <div class="menu-item" @mouseenter="showSubmenu = true" @mouseleave="showSubmenu = false">
    <div class="menu-item-content">
      {{ item.label }}
      <span v-if="item.children">▶</span>
    </div>

    <div v-if="item.children && showSubmenu" class="submenu">
      <Menu :items="item.children" @select="handleSelect"/>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import Menu from './Menu.vue';

const props = defineProps({
  item: Object
});

const emit = defineEmits(['select']);

const showSubmenu = ref(false);

const handleSelect = (item) => {
  emit('select', item);
};
</script>

<style scoped>
.menu-item {
  position: relative;
  padding: 8px 12px;
  cursor: pointer;
}

.menu-item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.submenu {
  position: absolute;
  left: 100%;
  top: 0;
  min-width: 150px;
  background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  border-radius: 4px;
}
</style>

使用 Vue Router 集成

当 Menu 需要与路由配合时,可以使用 Vue Router 的 <router-link>

<template>
  <div class="menu">
    <router-link
      v-for="item in items"
      :key="item.path"
      :to="item.path"
      class="menu-item"
      active-class="active"
    >
      {{ item.meta?.title || item.name }}
    </router-link>
  </div>
</template>

<script setup>
defineProps({
  items: {
    type: Array,
    required: true
  }
});
</script>

<style scoped>
.menu-item {
  display: block;
  padding: 8px 12px;
  text-decoration: none;
  color: inherit;
}

.active {
  background: #e0f2fe;
  color: #0369a1;
}
</style>

响应式设计

针对移动设备优化 Menu 显示:

<template>
  <button @click="toggleMenu">菜单</button>

  <div v-if="isOpen" class="mobile-menu">
    <div 
      v-for="item in items"
      :key="item.id"
      class="menu-item"
      @click="selectItem(item)"
    >
      {{ item.label }}
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const isOpen = ref(false);
const props = defineProps({
  items: Array
});

const toggleMenu = () => {
  isOpen.value = !isOpen.value;
};

const selectItem = (item) => {
  isOpen.value = false;
  emit('select', item);
};
</script>

<style scoped>
.mobile-menu {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: white;
  z-index: 100;
  padding: 20px;
}

@media (min-width: 768px) {
  .mobile-menu {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
  }
}
</style>

使用 UI 库

如果需要更完整的解决方案,可以考虑使用现成的 UI 库:

  1. Element Plus Menu 组件:

    <template>
    <el-menu
     :default-active="activeIndex"
     class="el-menu-demo"
     mode="horizontal"
     @select="handleSelect"
    >
     <el-menu-item index="1">首页</el-menu-item>
     <el-sub-menu index="2">
       <template #title>产品</template>
       <el-menu-item index="2-1">产品1</el-menu-item>
       <el-menu-item index="2-2">产品2</el-menu-item>
     </el-sub-menu>
    </el-menu>
    </template>
  2. Ant Design Vue Menu 组件:

    <template>
    <a-menu v-model:selectedKeys="current" mode="horizontal">
     <a-menu-item key="mail">导航1</a-menu-item>
     <a-menu-item key="app">导航2</a-menu-item>
     <a-sub-menu key="sub">
       <template #title>导航3</template>
       <a-menu-item key="sub1">选项1</a-menu-item>
       <a-menu-item key="sub2">选项2</a-menu-item>
     </a-sub-menu>
    </a-menu>
    </template>

vue实现menu

标签: vuemenu
分享给朋友:

相关文章

vue如何实现冒泡

vue如何实现冒泡

Vue 实现冒泡排序 在 Vue 中实现冒泡排序,可以通过数据绑定和响应式特性动态展示排序过程。以下是一个完整的实现示例,包含代码和详细说明。 数据准备 在 Vue 的 data 中定义一个数组作…

vue实现菜单调用

vue实现菜单调用

Vue 实现动态菜单的常见方法 基于路由配置生成菜单 Vue Router 的路由配置可以天然转化为菜单结构,适合权限与路由绑定的系统: // router/index.js const route…

vue为啥能实现监听

vue为啥能实现监听

Vue 实现监听的原理 Vue 的监听能力主要基于其响应式系统,该系统通过数据劫持和依赖收集实现。当数据变化时,系统能自动触发视图更新或执行回调函数。 核心机制:Object.defineProp…

vue怎么实现文件树

vue怎么实现文件树

Vue 实现文件树的方法 使用递归组件 递归组件是处理嵌套数据结构的理想方式。文件树通常包含文件夹和文件的嵌套结构,适合用递归组件实现。 <template> <ul>…

vue中如何实现循环

vue中如何实现循环

在 Vue 中实现循环 Vue 提供了 v-for 指令用于实现循环渲染列表数据。v-for 可以遍历数组、对象或数字范围,生成动态的 DOM 元素。 遍历数组 使用 v-for 遍历数组时,语法为…

vue状态管理怎么实现

vue状态管理怎么实现

Vue 状态管理实现方法 使用 Vuex(官方推荐) Vuex 是 Vue 的官方状态管理库,适合中大型应用。 安装 Vuex: npm install vuex --save 创建 Store…