vue与elementui实现递归组件菜单

主要讲如何使用vue实现一个递归组件,一般这种组件,多用于项目中的导航菜单。递归的主要思想就是自己调用自己,然后有结束条件。递归组件也是一样,在组建内使用自己(需要注意的是一个name属性,这个属性相当于组件的标识,自己调用自己就用的这个,其实keep-alive用到的exclude等也是这个属性而不是路由里面的name。),下面是我写的一个递归的导航菜单,毕竟看代码实例来的更清晰点。

  • 主菜单
<!--
 * @Autor: 卢建
 * @LastEditors: 卢建
 * @Description: 菜单
 * @Date: 2020-11-23 16:40:33
 * @LastEditTime: 2021-02-25 10:20:29
-->
<template>
  <div class="lj-left-menu">
    <el-menu
      :default-active="activeIndex"
      class="el-menu-vertical-demo"
      background-color="#242F4B"
      text-color="#D2D5DE"
      active-text-color="#468FFE"
      ref="activeIndex"
    >
      <menu-item :menuData="menuData"></menu-item>
    </el-menu>
  </div>
</template>

<script>
import menuItem from "./menuItem";
export default {
  name: "leftMenu",

  components: {
    menuItem,
  },

  data() {
    return {
      activeIndex: null, // 当前展开菜单
      menuData: [
        {
          id: "0",
          title: "首页",
          router: "/home",
          icon: "el-icon-s-home",
          children: [],
        },
        {
          id: "1",
          title: "巡检",
          icon: "el-icon-place",
          router: "/home",
          children: [
            {
              id: "1-0",
              title: "智能巡检设置",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "1-1",
              title: "巡检记录",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "1-2",
              title: "人工巡检任务",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "1-3",
              title: "故障维修",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "1-4",
              title: "保养维护任务",
              icon: "",
              router: "/home",
              children: [],
            },
          ],
        },
        {
          id: "2",
          title: "设备管理",
          icon: "el-icon-s-management",
          router: "",
          children: [
            {
              id: "2-0",
              title: "设备管理",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "2-1",
              title: "设备生命周期管理",
              icon: "",
              router: "/home",
              children: [],
            },
          ],
        },
        {
          id: "3",
          title: "告警管理",
          icon: "el-icon-sunrise",
          router: "/home",
          children: [
            {
              id: "3-0",
              title: "巡检告警",
              icon: "",
              router: "/home",
              children: [],
            },
          ],
        },
        {
          id: "4",
          title: "消息中心",
          icon: "el-icon-chat-dot-square",
          router: "/home",
          children: [
            {
              id: "4-0",
              title: "消息列表",
              icon: "",
              router: "/home",
              children: [],
            },
          ],
        },
        {
          id: "5",
          title: "系统管理",
          icon: "el-icon-setting",
          router: "/home",
          children: [
            {
              id: "5-0",
              title: "用户管理",
              icon: "",
              router: "/home",
              children: [
                {
                  id: "5-0-1",
                  title: "权限管理",
                  icon: "",
                  router: "/home",
                  children: [],
                },
              ],
            },
            {
              id: "5-1",
              title: "角色管理",
              icon: "",
              router: "/home",
              children: [],
            },
            {
              id: "5-2",
              title: "权限管理",
              icon: "",
              router: "/home",
              children: [],
            },
          ],
        },
      ],
    };
  },

  computed: {},

  mounted() {},

  methods: {},

  watch: {
    $route: { // 监听路由,确保刷新后当前页面与导航状态一致。
      handler(val) {
        this.activeIndex = val.meta.id;
      },
      deep: true,
      immediate: true,
    },
  },
};
</script>

<style lang='scss' scoped>
.lj-left-menu {
  width: 100%;
  height: 100%;
  overflow: auto;
}
</style>
  • 递归组件
<!--
 * @Autor: 卢建
 * @LastEditors: 卢建
 * @Description: 递归菜单
 * @Date: 2021-02-24 16:58:17
 * @LastEditTime: 2021-02-24 17:16:13
-->
<template>
  <div class="lj-menu-item">
    <template v-for="item in menuData">
      <template v-if="item.children.length">
        <el-submenu :index="item.id" :key="item.id">
          <template slot="title">
            <template v-if="item.icon">
              <i :class="item.icon"></i>
              <span>{{ item.title }}</span>
            </template>
            <template v-else>
              <div class="radius"></div>
              <div>{{ item.title }}</div>
            </template>
          </template>
          <menu-item :menuData="item.children"></menu-item>
        </el-submenu>
      </template>
      <template v-else>
        <el-menu-item
          :index="item.id"
          :key="item.id"
          @click="goRouter(item.router)"
        >
          <template v-if="item.icon">
            <i :class="item.icon"></i>
            <span>{{ item.title }}</span>
          </template>
          <template v-else>
            <div class="radius"></div>
            <div>{{ item.title }}</div>
          </template>
        </el-menu-item>
      </template>
    </template>
  </div>
</template>

<script>
export default {
  name: "menuItem",

  data() {
    return {
      nowRouter: null,
    };
  },

  props: {
    menuData: {
      type: Array,
      default: () => {},
    },
  },

  computed: {},

  mounted() {
    this.nowRouter = this.$route.path;
  },

  methods: {
    // 路由跳转
    goRouter(data) {
      if (this.nowRouter === data) {
        return;
      } else {
        this.nowRouter = data;
        this.$router.push(data);
      }
    },
  },
};
</script>

<style lang="scss">
.el-menu-item.is-active {
  background: linear-gradient(90deg, #2b579c 0%, rgba(52, 89, 150, 0) 100%);
  border-left: 2px solid #0086ff;
}
.el-menu-item:focus,
.el-menu-item:hover {
  background: linear-gradient(90deg, #2b579c 0%, rgba(52, 89, 150, 0) 100%);
  border-left: 2px solid #0086ff;
}
.el-submenu__title {
  i {
    color: #00d7ff !important;
  }
}
.el-menu-item,
.el-submenu__title {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  .radius {
    width: 8px;
    height: 8px;
    background: #468ffe;
    opacity: 0.6;
    border-radius: 50%;
    margin-right: 10px;
  }
  i {
    color: #00d7ff !important;
  }
}
</style>
Copyright © lujiannb@qq.com 2021 all right reserved,powered by Gitbook该文章修订时间: 2024-06-06 11:32:07

results matching ""

    No results matching ""