效果展示在这里插入图片描述

主要思路

运用递归的思想,循环所有菜单。如果菜单有子菜单,则把子菜单再循环一遍,直到没有子菜单为止。
(好像说了也不太明白,那就直接看实例代码吧!)

封装菜单组件

<template>
  <div>
    <!-- 这些是样式,可自定义 -->
    <el-menu
      background-color="#f3fbfe"
      text-color="#3C3C3C"
      active-text-color="#4d94dc"
      class="menu el-menu-vertical-menu"
    >
      <!-- 循环菜单数据 -->
      <label v-for="item in menuData" :key="item.index">
        <!-- 判断是否有子菜单,如果有就创建submenu,没有就创建menu-item -->
        <el-submenu :index="item.index" v-if="item.children">
          <template slot="title">
            <i :class="item.icon"></i>
            <span>{{ item.name }}</span>
          </template>
          <label>
            <!-- 自己调用自己 -->
            <menuDemo :menuData="item.children"></menuDemo>
          </label>
        </el-submenu>
        <el-menu-item v-else :index="item.index">
          <template slot="title">
            <i :class="item.icon"></i>
            <span>{{ item.name }}</span>
          </template>
        </el-menu-item>
      </label>
    </el-menu>
  </div>
</template>

<script>
import menuDemo from "@/components/menuDemo.vue";
export default {
  name: "menuDemo",
  components: {
    menuDemo,
  },
  props: {
    menuData: {
      type: Array,
    },
  },
  data() {
    return {};
  },
  created() {},
  methods: {},
};
</script>

<style scoped>
.menu {
  width: 180px !important;
  background-color: #f3fbfe;
  border-radius: 0.1rem;
  margin: 0 0 0 0.4rem;
  margin-bottom: 0.5rem;
  overflow-y: auto;
  overflow-x: hidden;
  display: block;
  position: relative;
}
</style>

这里比较难理解的就是,组件自己调用自己。这就是递归的思想,直到没有子菜单,循环才会结束。

菜单数据设计

可以自定义,这里应该是后端传过来的数据。这样就实现了后端对菜单的控制。
menuData: [
        {
          index: "1",
          name: "一级菜单1",
          icon: "el-icon-setting",
          children: [
            {
              index: "201",
              name: "二级菜单1",
              icon: "el-icon-s-platform",
              children: [
                {
                  index: "301",
                  name: "三级菜单1",
                  icon: "el-icon-s-platform",
                  children: [
                    {
                      index: "401",
                      name: "四级菜单1",
                      icon: "el-icon-s-platform",
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          index: "2",
          name: "一级菜单2",
          icon: "el-icon-s-tools",
          children: [
            {
              index: "202",
              name: "二级菜单2",
              icon: "el-icon-s-check",
            },
          ],
        },
        {
          index: "3",
          name: "一级菜单3",
          icon: "el-icon-s-tools",
        },
      ],

其他页面调用组件

<template>
  <div>
        <menuDemo :menuData="menuData"></menuDemo>
  </div>
</template>

<script>
import menuDemo from "@/components/menuDemo.vue";
export default {
  name: "",
  components: {
    menuDemo,
  },
  data() {
    return {
      menuData: [
        {
          index: "1",
          name: "一级菜单1",
          icon: "el-icon-setting",
          children: [
            {
              index: "201",
              name: "二级菜单1",
              icon: "el-icon-s-platform",
              children: [
                {
                  index: "301",
                  name: "三级菜单1",
                  icon: "el-icon-s-platform",
                  children: [
                    {
                      index: "401",
                      name: "四级菜单1",
                      icon: "el-icon-s-platform",
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          index: "2",
          name: "一级菜单2",
          icon: "el-icon-s-tools",
          children: [
            {
              index: "202",
              name: "二级菜单2",
              icon: "el-icon-s-check",
            },
          ],
        },
        {
          index: "3",
          name: "一级菜单3",
          icon: "el-icon-s-tools",
        },
      ],
    };
  },
  created() {},
  methods: {},
};
</script>

<style scoped>
</style>

到此,这个功能就实现了。

-------------------------这是一条华丽的分割线----------------------------

如果文章对您有帮助,请不要吝啬手中的赞哦!
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐