当前位置:首页 > 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>

vue实现menu

<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 库:

vue实现menu

  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>

标签: vuemenu
分享给朋友:

相关文章

vue实现分支

vue实现分支

Vue 实现分支的方法 在 Vue 项目中实现分支功能通常涉及条件渲染、动态组件或路由控制。以下是几种常见的实现方式: 条件渲染(v-if/v-show) 使用 Vue 的指令根据条件显示不同内容…

vue实现文档分享

vue实现文档分享

Vue 实现文档分享功能 文档分享功能通常涉及文件上传、存储、生成分享链接以及权限控制等模块。以下是基于 Vue 的实现方案: 文件上传组件 使用 element-ui 或 ant-design-v…

vue实现sql操作

vue实现sql操作

在Vue中实现SQL操作通常需要结合后端服务或本地数据库技术,因为前端JavaScript无法直接连接SQL数据库。以下是几种常见的实现方式: 通过API与后端交互 Vue前端通过HTTP请求(如…

项目基于vue实现

项目基于vue实现

基于Vue实现项目的关键方法 搭建基础环境 安装Node.js和npm/yarn,确保开发环境具备运行Vue的能力。通过Vue CLI快速初始化项目结构,选择所需配置(如Babel、Router、Vu…

vue实现好友列表

vue实现好友列表

实现好友列表的Vue组件 数据准备 在Vue组件的data中定义好友列表数据,通常是一个数组对象,每个对象包含好友的基本信息如ID、头像、昵称等。 data() { return { f…

vue实现压缩上传文件

vue实现压缩上传文件

压缩上传文件的实现方法 在Vue中实现文件压缩和上传功能,可以通过以下步骤完成。该方法结合了前端文件压缩库和HTTP请求,确保文件在上传前被有效压缩。 安装必要的依赖 需要使用compressor…