当前位置:首页 > 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原型实现

Vue 原型实现的关键点 Vue.js 的原型系统是其响应式机制的核心部分,通过原型链实现数据的动态绑定和依赖收集。以下是实现 Vue 原型的主要技术要点。 数据响应式原理 Vue 通过 Objec…

vue实现https

vue实现https

Vue 中实现 HTTPS 的步骤 在 Vue 项目中实现 HTTPS 主要涉及开发环境配置和生产环境部署。以下是具体方法: 开发环境配置(Vue CLI 或 Vite) 使用 mkcert…

vue实现swipe

vue实现swipe

Vue实现Swipe功能的方法 使用第三方库(推荐) Vue生态中有多个成熟的轮播/滑动组件库,例如vue-awesome-swiper或swiper/vue。以下是基于swiper/vue的实现示例…

vue 实现拖拉

vue 实现拖拉

Vue 实现拖拽功能的方法 使用 HTML5 原生拖放 API HTML5 提供了原生的拖放 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 dr…

vue实现api

vue实现api

Vue 实现 API 调用 在 Vue 中调用 API 通常涉及使用 axios 或 fetch 发送 HTTP 请求,并结合 Vue 的响应式特性管理数据。以下是常见的实现方式: 安装 axi…