vue+element ui 后台管理系统(递归生成可伸缩侧边栏)

最近在做一个基于vue+element的后台管理系统 做了一个可伸缩的 侧边栏 记录下 在很多管理系统都能用到 。

首先是收起时候

1. 做的过程中折叠出现的问题:

  1. 没有子菜单折叠时,icon会隐藏
  2. 有子菜单折叠时,箭头不隐藏
    在这里插入图片描述

解决:

  1. treemenu.vue 中没有子菜单时,比如侧边栏的首页就没有子菜单,去掉 <template slot="title">就好了
  2. 箭头不隐藏问题,在sidebar.vue中增加样式.el-icon-arrow-right { display: none; }

2. 发现侧边栏跳转不了问题:
重点提示:

必须设置:default-active="$route.name":router="true"

  1. el-submenu之 index属性: 这个index表示每一组的唯一标志,当我们定义了 unique-opened=true的时候会根据这个标识展示相应的选项。自己可以测试一下把所有的选项组的index都设置成同一个值得时候是什么效果就明白了这个标志得作用。
  2. el-menu-item 之index属性:这个index值会被作为跳转路径进行跳转,我们需要把这个值和页面路径对应起来。所以需要开启路由模式,点击哪个页面的时候左侧就会显示哪个页面内容信息。

3. 递归生成侧边栏

有一个菜单树,顶层菜单下面有多个子菜单,子菜单下还有子菜单。。。
这时候就要用递归处理。我现在项目里还没有这个需求,但防止后面需求会有,我还是用递归做的侧边栏

首先是新建一个sidebar.vue

<template>
  <el-aside :width="isCollapse ? '64px' : '200px'" id="sidebar" class="sidebar">
    <el-scrollbar class="scrollbar-wrapper">
      <div class="el-icon-user-solid subhead-headImg">
        <div>{{ username }}</div>
      </div>
      <div class="toggle-button" @click="toggleCollapse">|||</div>
      <!-- 侧边栏菜单区域 -->
      <el-menu
        background-color="#333d54"
        text-color="rgba(255,255,255,0.5)"
        active-text-color="rgba(255,255,255)"
        :default-active="$route.name"
        @select="handleSel"
        :collapse="isCollapse"
        :collapse-transition="false"
        :unique-opened="true"
        :router="true"
        v-if="sidebarList"
      >
        <div v-for="(item, index) in sidebarList" :key="index">
          <TreeMenu :treedata="item"></TreeMenu>
        </div>
      </el-menu>
    </el-scrollbar>
  </el-aside>
</template>
<script>
import path from "path";
import sideBar from "@/meta/sidebar";
import TreeMenu from "@/components/tree/treemenu";
export default {
  name: "Sidebar",
  components: {
    TreeMenu
  },
  data() {
    return {
      // 是否折叠
      isCollapse: false,
      openMenu: [],
      username: ""
    };
  },
  computed: {
    sidebarList() {
      return sideBar.mainbar();
    }
  },
  methods: {
    handleSel(key, keyPath) {
      console.log(path.resolve(process.cwd(), ...keyPath));
      let sitePath = path.resolve(process.cwd(), ...keyPath);
      this.$router.push({ path: sitePath });
    },
    // 点击按钮,切换菜单的折叠与展开
    toggleCollapse() {
      this.isCollapse = !this.isCollapse;
    }
  },
  created() {
    // this.setSidebarList('mainbar')
    this.sidebarList.forEach(item => {
      this.openMenu.push(item.key);
    });
  },
  mounted() {
    this.username = sessionStorage.getItem("username");
  },
  watch: {
    sidebarList() {
      if (this.sidebarList) {
        this.sidebarList.forEach(item => {
          this.openMenu.push(item.key);
        });
      }
    }
  }
};
</script>
<style lang="scss" scope>
.sidebar {
  height: 100%;
}
.toggle-button {
  background-color: #4a5064;
  font-size: 10px;
  line-height: 24px;
  color: #fff;
  text-align: center;
  letter-spacing: 0.2em;
  cursor: pointer;
}
// 隐藏箭头
.el-icon-arrow-right {
  display: none;
}
</style>

treemenu.vue

<template>
  <div>
    <el-submenu
      v-if="treedata.child && treedata.child.length > 0"
      :index="treedata.key"
    >
      <template slot="title">
        <i :class="treedata.ico" v-if="treedata.ico"></i>
        <span slot="title">{{ treedata.value }}</span>
      </template>
      <div v-for="(children, index) in treedata.child" v-bind:key="index">
      <!--递归调用自身,这里主要根据name的名字-->
        <treeItem :treedata="children"></treeItem>
      </div>
    </el-submenu>
    <el-menu-item v-else :index="treedata.key">
      <i :class="treedata.ico" v-if="treedata.ico"></i>
      <span slot="title">{{ treedata.value }}</span>
    </el-menu-item>
  </div>
</template>
<script>
export default {
  name: "treeItem",
  props: ["treedata"],
  data() {
    return {};
  }
};
</script>
<style lang="scss" scoped>
/*隐藏文字*/
.el-menu--collapse .el-submenu__title span {
  display: none;
}
</style>

sidebar.js

const staticBar = [
  {
    key: 'index',
    ico: 'el-icon-document',
    value: '导航一',
  },
  {
    key: 'permission',
    ico: 'el-icon-data-line',
    value: '导航二',
    child:[{
      key: 'adminlist',
      ico: 'el-icon-document',
      value: '选项1',
    },
    {
      key: 'role',
      ico: 'el-icon-document',
      value: '选项2',
    },
    {
      key: 'authManage',
      ico: 'el-icon-document',
      value: '选项3',
    }]
  },
  {
    key: 'member',
    ico: 'el-icon-printer',
    value: '导航三',
    child:[{
      key: '/member/memberList',
      ico: 'el-icon-document',
      value: '选项1',
    },
    {
      key: '/member/memberSearch',
      ico: 'el-icon-document',
      value: '选项2',
    },
    {
      key: 'New_business',
      ico: 'el-icon-document',
      value: '选项3',
    },
    {
      key: 'Real_name',
      ico: 'el-icon-document',
      value: '选项4',
    },
    {
      key: 'invitation',
      ico: 'el-icon-document',
      value: '选项5',
    }]
},
]

最终实现折叠效果:
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁锤妹妹@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值