用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 API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
28天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
128 64
|
7天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
28天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
32 8
|
28天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
1月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
JavaScript
Vue的非父子组件之间传值
全局事件总线 一种组件间通信的方式,适用于任意组件间通信
|
缓存 JavaScript 前端开发
Vue Props、Slot、v-once、非父子组件间的传值....
Vue Props、Slot、v-once、非父子组件间的传值....
87 0
|
JavaScript
Vue中父子组件传值
先在⽗组件中给⼦组件的⾃定义属性绑定⼀个⽗组件的变量
|
JavaScript
vue 组件传值
vue 组件传值
86 0

热门文章

最新文章