用Vue写一个简单好看的菜单组件(Vue实战系列)

简介: 用Vue写一个简单好看的菜单组件(Vue实战系列)

前端开发中,Vue.js已经成为一个非常流行的框架,它以其简洁的语法和强大的功能吸引了大量的开发者。今天,我们将一起使用Vue.js来创建一个简单而美观的菜单组件。

一、准备工作

在开始之前,请确保你已经安装了Vue.js。你可以通过Vue CLI来创建一个新的Vue项目,或者在你的现有项目中引入Vue.js。

需求

  1. 实现一个左边栏菜单,菜单只包括两层;
  2. 点击出现水波纹效果;
  1. 激活效果:有一个绿球小点,标识激活的菜单,顶层菜单被激活时左边出现浅色激活标志;

二、实现

1. 新建一个菜单组件whrmenu

组件接收的参数

我们希望可以定制小球的颜色,菜单数据,父级菜单激活的侧边框颜色

  props: {
    //菜单数据必输是数组 包含 url title icon children
      menu: {
        type: Array,
        required: true,
      },
      //父级激活左边阴影颜色
      pletcolor: {
        type: String,
        default: "#856ab5",
      },
      //小球颜色
      pointcolor: {
        type: String,
        default: "#1ab3a3",
      },

  },

这个菜单长这个样子,菜单的数据:

  menu: [
        {
          title: "题库管理",
          url: "/index/questionlist",
          icon: "el-icon-files",
          children: [
            {
              title: "题库列表",
              url: "/index/question/questionlist",
            },
          ],
        },
        {
          title: "活动管理",
          url: "/index/activity",
          icon: "el-icon-help",
          children: [
            {
              title: "活动列表",
              url: "/index/activity/activitylist",
            },
          ],
        },
        {
          title: "系统设置",
          url: "/index/sys",
          icon: "el-icon-setting",
          children: [
            {
              title: "用户管理",
              url: "/index/sys/user",
            },
          ],
        },
      ],

2. 拿到这个菜单,我们需要处理一下,如果menu有子菜单,那么就给加一个isexpand的属性,方便之后的做展开操作。

用一个计算属性修改一下menu

每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。

如果你这样做了,Vue 会在浏览器的控制台中发出警告。

这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

  menus(){
      let menus = this.menu.map(item=>{
        if(item.children){
          item.isexpand = false;
        }
        return item
      })
      return menus
    }

3. vue的template部分模版代码

<div class="whr-menu">
      <div
          v-for="(item,index) in menus"
          :key="index"
      >
        <div
            v-ripple
            class="whr-pmenu-item"
            :class="{activeMenu:activeItem == item.url}"
            @click="clickitem(item,index)"
        >
          <div style="display:flex;">
            <div style="width:30px">
              <i
                  :class="item.icon"
                  style="margin-right:20px"
              ></i>
            </div>
            <div>
              {{ item.title }}
            </div>
            <div
                class="xiaoqiu"
                v-show="!item.isexpand && pgreen == item.url"
                :style="{ backgroundColor: pointcolor }"
            ></div>
          </div>

        </div>

        <div
            v-if="item.children"
            class="childrendiv"
            :class="{havechildren:item.isexpand}"
        >
          <div
              v-ripple
              class="whr-sbmenu-item"
              :class="{activesbMenu:activesbItem == sb_item.url}"
              @click="clicksbitem(sb_item,item)"
              v-for="(sb_item,sb_index) in item.children"
              :key="sb_index"
          >
            {{ sb_item.title }}
            <div
                class="xiaoqiu"
                v-show="$route.path == sb_item.url"
                :style="{ backgroundColor: pointcolor }"
            ></div>
          </div>
        </div>
      </div>

    </div>

4. 菜单的点击事件

  clickitem(item,index) {
      this.menus[index].isexpand = !item.isexpand;
      this.activeItem = item.url;
      if (item.children) {
        //有子菜单,设置子元素高度
        this.activeLength = item.children.length * 49 + 20 + "px";
      }
      this.$emit("dianp", item);
      console.log("当前激活父级菜单", this.activeItem);
    },
    clicksbitem(item, pitem) {
      //点击子菜单
      this.activesbItem = item.url;
      this.activeItem = pitem.url;
      this.$emit("dianc", {item, pitem});
    },

点击父级菜单和点击子菜单的逻辑我先写的不一样,以后可以简化再改,主要记录一下当前菜单的url;

父级菜单的这个小绿点有些麻烦,当激活的菜单是这个父级菜单的子菜单而且这个父级菜单没有展开的时候才加这个小绿点。

5. 做一个计算属性,看看当前激活的菜单在不在这个父级菜单里面,返回这个绿点应该在的位置:

//父级菜单绿点位置
    pgreen() {
      let u = [];
      u = this.menus.filter(item=>{
        let xu = []
        if(item.children.length>0){
          xu = item.children.filter(i=>{
            return i.url == this.$route.path
          })
          if(xu.length>0){
            return true
          } else {
            return false
          }
        }else {
          return item.url == this.$route.path
        }
      })
      return u[0].url
    },

使用Vue.js创建一个简单而美观的菜单组件

在前端开发中,Vue.js已经成为一个非常流行的框架,它以其简洁的语法和强大的功能吸引了大量的开发者。今天,我们将一起使用Vue.js来创建一个简单而美观的菜单组件。

三、组件解析

  1. 模板部分:我们使用了一个无序列表来显示菜单项,每个菜单项都是一个链接。我们使用了Vue的v-for指令来循环遍历items数组,并为每个菜单项生成一个列表项。我们还使用了v-bind指令(简写为:)来动态绑定classkey属性。
  2. 脚本部分:我们在data函数中定义了一个items数组来存储菜单项,以及一个currentIndex变量来跟踪当前选中的菜单项。我们还定义了一个selectItem方法来更新currentIndex的值。
  3. 样式部分:我们为菜单组件添加了一些基本的样式,包括背景颜色、内边距、文字颜色等。我们还为当前选中的菜单项添加了一个不同的背景颜色和文字颜色。

四、使用菜单组件

现在,你可以在你的Vue应用程序中使用这个菜单组件。首先,你需要在你的父组件中导入并注册这个组件,然后在模板中使用它。

<template>
  <div>
    <Menu />
    <!-- 其他内容 -->
  </div>
</template>

<script>
import Menu from './Menu.vue';

export default {
  components: {
    Menu
  }
};
</script>

五、总结

通过以上的步骤,我们成功地创建了一个简单而美观的菜单组件。这个组件使用了Vue.js的一些基本功能,包括模板语法、数据绑定和事件处理。你可以根据你的需求对这个组件进行扩展和定制,例如添加子菜单、下拉菜单等功能。希望这篇文章能对你有所帮助!

喜欢的小伙伴留言点赞关注吧!

相关文章
|
1天前
|
JavaScript
如何在 Vue 项目中选择合适的模块格式
【10月更文挑战第20天】选择合适的模块格式需要综合考虑多个因素,没有一种绝对正确的选择。需要根据项目的具体情况进行权衡和分析。在实际选择过程中,要保持灵活性,根据项目的发展和变化适时调整模块格式。
14 7
|
1天前
|
JavaScript 前端开发 编译器
在 Vue 项目中使用 ES 模块格式的优点
【10月更文挑战第20天】在 Vue 项目中使用 ES 模块格式具有众多优点,这些优点共同作用,使得项目能够更高效、更可靠地开发和运行。当然,在实际应用中,还需要根据项目的具体情况和需求进行合理的选择和配置。
14 6
|
1天前
|
JavaScript 前端开发 开发者
Vue 的优缺点
【10月更文挑战第16天】Vue 具有众多优点,使其成为前端开发中备受青睐的框架之一。尽管它也存在一些局限性,但通过合理的应用和技术选型,这些问题可以得到一定程度的解决。在实际项目中,开发者可以根据项目的需求和特点,权衡 Vue 的优缺点,选择最适合的技术方案。同时,随着 Vue 不断的发展和完善,相信它将在前端开发领域继续发挥重要作用。
11 6
|
1天前
|
前端开发 UED
vue3知识点:Suspense组件
vue3知识点:Suspense组件
11 4
|
1天前
|
JavaScript 前端开发 Java
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
10 2
|
1天前
|
Java
vue3知识点:Teleport组件
vue3知识点:Teleport组件
10 1
|
3天前
|
JavaScript
在 Vue 中处理组件选项与 Mixin 选项冲突的详细解决方案
【10月更文挑战第18天】通过以上的分析和探讨,相信你对在 Vue 中使用 Mixin 时遇到组件选项与 Mixin 选项冲突的解决方法有了更深入的理解。在实际开发中,要根据具体情况灵活选择合适的解决方案,以确保代码的质量和可维护性。
27 7
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1043 0
|
3天前
|
存储 JavaScript
vue——store全局存储
【10月更文挑战第18天】Vuex 是 Vue.js 应用中非常重要的一个工具,它为我们提供了一种有效的状态管理方式。通过合理地使用 Vuex,我们可以更好地组织和管理应用的状态,提高应用的开发效率和质量。
15 1
|
2天前
|
缓存 JavaScript UED
Vue 的动态组件与 keep-alive
【10月更文挑战第19天】总的来说,动态组件和 `keep-alive` 是 Vue.js 中非常实用的特性,它们为我们提供了更灵活和高效的组件管理方式,使我们能够更好地构建复杂的应用界面。深入理解和掌握它们,以便在实际开发中能够充分发挥它们的优势,提升我们的开发效率和应用性能。
29 18