用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的一些基本功能,包括模板语法、数据绑定和事件处理。你可以根据你的需求对这个组件进行扩展和定制,例如添加子菜单、下拉菜单等功能。希望这篇文章能对你有所帮助!

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

相关文章
|
5月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
485 2
|
4月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
407 137
|
7月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
556 1
|
7月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
371 0
|
8月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
940 0
|
10月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1204 4
|
8月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
9月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1194 78
|
10月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
8月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
574 17

热门文章

最新文章