index.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <template>
  2. <el-popover :default-active="activeMenu" placement="bottom" width="400" trigger="click" style="margin-top: 44px" v-model="isShowMenu">
  3. <div class="cbox">
  4. <div class="lable">菜单入口</div>
  5. <div class="menu" v-for="(item, index) in topMenus" @click="handleSelect(item)">
  6. <div class="out">
  7. <div class="int">
  8. <div class="icon"><svg-icon :icon-class="item.meta.icon" /></div>
  9. <div class="desc">{{ item.meta.title }}</div>
  10. </div>
  11. </div>
  12. </div>
  13. </div>
  14. <div slot="reference" class="reference" >
  15. <span class="icon">&#xe608;</span>
  16. <div class="mtt">应用中心</div>
  17. </div>
  18. </el-popover>
  19. </template>
  20. <script>
  21. import { constantRoutes } from '@/router';
  22. // 隐藏侧边栏路由
  23. const hideList = ['/index', '/user/profile'];
  24. export default {
  25. data() {
  26. return {
  27. isShowMenu: false,
  28. // 当前激活菜单的 index
  29. currentIndex: undefined
  30. };
  31. },
  32. computed: {
  33. theme() {
  34. return this.$store.state.settings.theme;
  35. },
  36. // 顶部显示菜单
  37. topMenus() {
  38. let topMenus = [];
  39. this.routers.map(menu => {
  40. if (menu.hidden !== true) {
  41. // 兼容顶部栏一级菜单内部跳转
  42. if (menu.path === '/') {
  43. topMenus.push(menu.children[0]);
  44. } else {
  45. topMenus.push(menu);
  46. }
  47. }
  48. });
  49. return topMenus;
  50. },
  51. // 所有的路由信息
  52. routers() {
  53. return this.$store.state.permission.topbarRouters;
  54. },
  55. // 设置子路由
  56. childrenMenus() {
  57. var childrenMenus = [];
  58. this.routers.map(router => {
  59. for (var item in router.children) {
  60. if (router.children[item].parentPath === undefined) {
  61. if (router.path === '/') {
  62. router.children[item].path = '/' + router.children[item].path;
  63. } else {
  64. if (!this.ishttp(router.children[item].path)) {
  65. router.children[item].path = router.path + '/' + router.children[item].path;
  66. }
  67. }
  68. router.children[item].parentPath = router.path;
  69. }
  70. childrenMenus.push(router.children[item]);
  71. }
  72. });
  73. return constantRoutes.concat(childrenMenus);
  74. },
  75. // 默认激活的菜单
  76. activeMenu() {
  77. const path = this.$route.path;
  78. let activePath = path;
  79. if (path !== undefined && path.lastIndexOf('/') > 0 && hideList.indexOf(path) === -1) {
  80. const tmpPath = path.substring(1, path.length);
  81. activePath = '/' + tmpPath.substring(0, tmpPath.indexOf('/'));
  82. this.$store.dispatch('app/toggleSideBarHide', false);
  83. } else if (!this.$route.children) {
  84. activePath = path;
  85. this.$store.dispatch('app/toggleSideBarHide', true);
  86. }
  87. this.activeRoutes(activePath);
  88. return activePath;
  89. }
  90. },
  91. beforeMount() {
  92. window.addEventListener('resize', this.setVisibleNumber);
  93. },
  94. beforeDestroy() {
  95. window.removeEventListener('resize', this.setVisibleNumber);
  96. },
  97. mounted() {
  98. this.setVisibleNumber();
  99. },
  100. methods: {
  101. closeMenuHandler() {
  102. this.$emit('closeMenuHandler');
  103. },
  104. // 根据宽度计算设置显示栏数
  105. setVisibleNumber() {
  106. const width = document.body.getBoundingClientRect().width / 3;
  107. this.visibleNumber = parseInt(width / 85);
  108. },
  109. // 菜单选择事件
  110. handleSelect(item) {
  111. this.isShowMenu = false;
  112. this.currentIndex = item.path;
  113. let key = item.path;
  114. const route = this.routers.find(item => item.path === key);
  115. if (this.ishttp(key)) {
  116. // http(s):// 路径新窗口打开
  117. window.open(key, '_blank');
  118. } else if (!route || !route.children) {
  119. // 没有子路由路径内部打开
  120. this.$router.push({ path: key });
  121. this.$store.dispatch('app/toggleSideBarHide', true);
  122. } else {
  123. // 显示左侧联动菜单
  124. this.activeRoutes(key);
  125. this.$store.dispatch('app/toggleSideBarHide', false);
  126. }
  127. this.$emit('showHamBurger');
  128. this.$emit('closeMenuHandler');
  129. },
  130. // 当前激活的路由
  131. activeRoutes(key) {
  132. var routes = [];
  133. if (this.childrenMenus && this.childrenMenus.length > 0) {
  134. this.childrenMenus.map(item => {
  135. if (key == item.parentPath || (key == 'index' && '' == item.path)) {
  136. routes.push(item);
  137. }
  138. });
  139. }
  140. if (routes.length > 0) {
  141. this.$store.commit('SET_SIDEBAR_ROUTERS', routes);
  142. }
  143. },
  144. ishttp(url) {
  145. return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
  146. }
  147. }
  148. };
  149. </script>
  150. <style lang="scss">
  151. .testgks {
  152. margin-left: 12vw;
  153. }
  154. .topmenu-container.el-menu--horizontal > .el-menu-item {
  155. float: left;
  156. height: 50px !important;
  157. line-height: 50px !important;
  158. color: #999093 !important;
  159. padding: 0 5px !important;
  160. margin: 0 10px !important;
  161. }
  162. .topmenu-container.el-menu--horizontal > .el-menu-item.is-active,
  163. .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
  164. border-bottom: 2px solid #{'var(--theme)'} !important;
  165. color: #303133;
  166. }
  167. /* submenu item */
  168. .topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
  169. float: left;
  170. height: 50px !important;
  171. line-height: 50px !important;
  172. color: #999093 !important;
  173. padding: 0 5px !important;
  174. margin: 0 10px !important;
  175. }
  176. .reference {
  177. margin-top: -2px;
  178. .mtt {
  179. margin-top: -24px;
  180. font-size: 14px;
  181. }
  182. }
  183. .el-popper {
  184. top: 44px !important;
  185. }
  186. .menu {
  187. float: left;
  188. width: 33.33%;
  189. .out {
  190. padding: 10px;
  191. .int {
  192. padding: 10px 10px 0px 10px;
  193. text-align: center;
  194. cursor: pointer;
  195. .icon {
  196. width: 45px;
  197. height: 45px;
  198. color: white;
  199. border-radius: 12px;
  200. margin: 0 auto;
  201. font-size: 23px;
  202. line-height: 45px;
  203. background-color: rgb(37, 97, 239);
  204. color: white;
  205. }
  206. .desc {
  207. color: #545555;
  208. margin-top: 9px;
  209. font-size: 14px;
  210. }
  211. }
  212. }
  213. }
  214. </style>