Sidebar.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <div id="Sidebar">
  3. <el-row class="sidebar">
  4. <el-col :span="24" class="main">
  5. <el-col :span="24" class="one">
  6. <el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="false" unique-opened router>
  7. <template v-for="item in items">
  8. <!-- 二级菜单 -->
  9. <template v-if="item.type === '0'">
  10. <el-submenu :index="item._id || item.index" :key="item._id">
  11. <template slot="title">
  12. <i :class="['iconfont', item.icon]"></i>
  13. <span slot="title">{{ item.name }}</span>
  14. </template>
  15. <template v-for="subItem in item.children">
  16. <!-- 三级菜单 -->
  17. <el-submenu
  18. v-if="subItem.children && subItem.children.length > 0 && subItem.children.every((f) => f.type === '0' || f.type === '1')"
  19. :index="subItem._id"
  20. :key="subItem._id"
  21. >
  22. <template slot="title">
  23. <i :class="['iconfont', subItem.icon]"></i>
  24. <span slot="title">{{ subItem.name }}</span>
  25. </template>
  26. <el-menu-item v-for="(threeItem, i) in subItem.children" :key="i" :index="threeItem.path">
  27. <template slot="title">
  28. <i :class="['iconfont', threeItem.icon]"></i>
  29. <span slot="title">{{ threeItem.name }}</span>
  30. </template>
  31. </el-menu-item>
  32. </el-submenu>
  33. <el-menu-item v-else :index="subItem.path" :key="subItem.path">
  34. <template slot="title">
  35. <i :class="['iconfont', subItem.icon]"></i>
  36. <span slot="title">{{ subItem.name }}</span>
  37. </template>
  38. </el-menu-item>
  39. </template>
  40. </el-submenu>
  41. </template>
  42. <!-- 一级菜单 -->
  43. <template v-else>
  44. <el-menu-item class="first" :index="item.path" :key="item.path">
  45. <i :class="['iconfont', item.icon]"></i>
  46. <span slot="title">{{ item.name }}</span>
  47. </el-menu-item>
  48. </template>
  49. </template>
  50. </el-menu>
  51. </el-col>
  52. </el-col>
  53. </el-row>
  54. </div>
  55. </template>
  56. <script>
  57. const { system, adminMenu, devMenu } = require('./data/menu');
  58. const { menuInfo } = require('./data/site');
  59. import { mapState, createNamespacedHelpers } from 'vuex';
  60. import _ from 'lodash';
  61. import bus from './bus';
  62. export default {
  63. name: 'Sidebar',
  64. props: {},
  65. components: {},
  66. data: function () {
  67. return {
  68. menuInfo: menuInfo,
  69. collapse: false,
  70. items: [...system, ...adminMenu],
  71. };
  72. },
  73. created() {
  74. bus.$on('collapse', (msg) => {
  75. this.collapse = msg;
  76. bus.$emit('collapse-content', msg);
  77. });
  78. },
  79. methods: {
  80. async getMenu() {
  81. const { options } = this.$router;
  82. if (!options) {
  83. console.warn('获取菜单:解析base错误');
  84. return;
  85. }
  86. if (this.$dev_env) this.items.unshift(...devMenu);
  87. },
  88. },
  89. computed: {
  90. ...mapState(['user', 'menuList']),
  91. onRoutes() {
  92. return this.$route.path;
  93. },
  94. },
  95. metaInfo() {
  96. return { title: this.$route.meta.title };
  97. },
  98. watch: {
  99. user: {
  100. deep: true,
  101. immediate: true,
  102. handler(val) {
  103. this.getMenu();
  104. },
  105. },
  106. },
  107. };
  108. </script>
  109. <style lang="less" scoped>
  110. .sidebar {
  111. display: block;
  112. position: absolute;
  113. left: 0;
  114. top: 60px;
  115. bottom: 0;
  116. overflow-y: scroll;
  117. }
  118. .sidebar::-webkit-scrollbar {
  119. width: 0;
  120. }
  121. .sidebar-el-menu:not(.el-menu--collapse) {
  122. width: 200px;
  123. }
  124. .sidebar > ul {
  125. height: 100%;
  126. }
  127. .main {
  128. .one {
  129. .iconfont {
  130. font-size: 18px;
  131. margin: 0 5px 0 0;
  132. }
  133. }
  134. }
  135. </style>