index.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <template>
  2. <el-menu
  3. class="top-submenu"
  4. :default-active="activeMenu"
  5. mode="horizontal"
  6. >
  7. <template v-for="(item, index) in topMenus">
  8. <el-menu-item :style="{'--theme': theme}" @click="handleSelect(item)" :index="item.path" :key="index" v-if="index < visibleNumber">
  9. <!--<svg-icon :icon-class="item.meta.icon" />-->
  10. {{ item.meta.title }}
  11. </el-menu-item>
  12. </template>
  13. <!-- 顶部菜单超出数量折叠 -->
  14. <el-submenu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
  15. <template slot="title">更多</template>
  16. <template v-for="(item, index) in topMenus">
  17. <el-menu-item
  18. @click="handleSelect(item)"
  19. class="all-menu"
  20. :index="item.path"
  21. :key="index"
  22. v-if="index >= visibleNumber">
  23. <!--<svg-icon :icon-class="item.meta.icon" />-->
  24. {{ item.meta.title }}
  25. </el-menu-item>
  26. </template>
  27. </el-submenu>
  28. </el-menu>
  29. </template>
  30. <script>
  31. import { constantRoutes } from "@/router";
  32. import store from '@/store'
  33. export default {
  34. data() {
  35. return {
  36. // 顶部栏初始数
  37. visibleNumber: 5,
  38. // 是否为首次加载
  39. isFrist: false,
  40. // 当前激活菜单的 index
  41. currentIndex: undefined,
  42. routerType:true,
  43. };
  44. },
  45. computed: {
  46. theme() {
  47. return this.$store.state.settings.theme;
  48. },
  49. // 顶部显示菜单
  50. topMenus() {
  51. let topMenus = [];
  52. this.routers.map((menu) => {
  53. if (menu.hidden !== true) {
  54. // 兼容顶部栏一级菜单内部跳转
  55. if (menu.path === "/") {
  56. topMenus.push(menu.children[0]);
  57. } else {
  58. topMenus.push(menu);
  59. }
  60. }
  61. });
  62. return topMenus;
  63. },
  64. // 所有的路由信息
  65. routers() {
  66. return this.$store.state.permission.topbarRouters;
  67. },
  68. // 设置子路由
  69. childrenMenus() {
  70. var childrenMenus = [];
  71. this.routers.map((router) => {
  72. for (var item in router.children) {
  73. if (router.children[item].parentPath === undefined) {
  74. if(router.path === "/") {
  75. router.children[item].path = "/redirect/" + router.children[item].path;
  76. } else {
  77. if(!this.ishttp(router.children[item].path)) {
  78. router.children[item].path = router.path + "/" + router.children[item].path;
  79. }
  80. }
  81. router.children[item].parentPath = router.path;
  82. }
  83. childrenMenus.push(router.children[item]);
  84. }
  85. });
  86. return constantRoutes.concat(childrenMenus);
  87. },
  88. // 默认激活的菜单
  89. activeMenu() {
  90. const path = this.$route.path;
  91. let activePath = this.defaultRouter();
  92. if (path.lastIndexOf("/") > 0) {
  93. const tmpPath = path.substring(1, path.length);
  94. activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
  95. } else if ("/index" == path || "" == path) {
  96. if (!this.isFrist) {
  97. this.isFrist = true;
  98. } else {
  99. activePath = "index";
  100. }
  101. }
  102. if(this.routerType){
  103. this.routerType = false;
  104. var routes = this.activeRoutes(activePath);
  105. if (routes.length === 0) {
  106. activePath = this.currentIndex || this.defaultRouter()
  107. this.activeRoutes(activePath);
  108. }
  109. }
  110. return activePath;
  111. },
  112. },
  113. beforeMount() {
  114. window.addEventListener('resize', this.setVisibleNumber)
  115. },
  116. beforeDestroy() {
  117. window.removeEventListener('resize', this.setVisibleNumber)
  118. },
  119. mounted() {
  120. this.setVisibleNumber();
  121. },
  122. methods: {
  123. // 根据宽度计算设置显示栏数
  124. setVisibleNumber() {
  125. const width = document.body.getBoundingClientRect().width / 3;
  126. // this.visibleNumber = parseInt(width / 85);
  127. },
  128. // 默认激活的路由
  129. defaultRouter() {
  130. let self = this;
  131. let router;
  132. Object.keys(this.routers).some((key) => {
  133. if (!this.routers[key].hidden) {
  134. router = this.routers[key].path;
  135. return true;
  136. }
  137. });
  138. let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
  139. for(let i=0;i<self.topMenus.length;i++){
  140. if(matched[0]){
  141. if(matched[0].path == self.topMenus[i].path){
  142. if(matched[0].meta.title != '数据可视化'){
  143. store.dispatch('settings/setPageName', matched[0].meta.title)
  144. }
  145. }
  146. }
  147. }
  148. return router;
  149. },
  150. // 菜单选择事件
  151. handleSelect(item) {
  152. if(item.isFrame){
  153. this.xmlRequestSkip(item);
  154. }else{
  155. if(item.children){
  156. this.currentIndex = item.path;
  157. this.activeRoutes(item.path);
  158. for(let i=0;i<item.children.length;i++){
  159. if(item.children[i].children){
  160. for(let o=0;o<item.children[i].children.length;o++){
  161. if(!item.children[i].children[o].isFrame){
  162. //路由跳转
  163. this.$router.push({
  164. path: item.children[i].path+'/'+item.children[i].children[o].path
  165. });
  166. return
  167. }
  168. }
  169. }else{
  170. if(!item.children[i].isFrame){
  171. //路由跳转
  172. this.$router.push({
  173. path: item.children[i].path
  174. });
  175. return
  176. }
  177. }
  178. }
  179. // this.msgError('该目录没有可跳转的页面')
  180. }else{
  181. this.msgError('这是一个空目录')
  182. }
  183. }
  184. },
  185. //链接跳转方法
  186. xmlRequestSkip(item){
  187. let self = this;
  188. if(item.needAuth){
  189. let urlText = window.location.href.split('://')[0]+'://';
  190. //链接请求跳转
  191. let formData = new FormData();
  192. item.params.customParameter.forEach((item)=>{
  193. formData.append(item.key,item.value);
  194. })
  195. let xhr = new XMLHttpRequest();
  196. xhr.onreadystatechange = function() {
  197. if (xhr.readyState === XMLHttpRequest.DONE) {
  198. if (xhr.status === 200) {
  199. window.open(item.name,item.params.skipType)
  200. } else {
  201. self.msgError('操作失败,请联系管理员')
  202. }
  203. }
  204. };
  205. xhr.open(item.params.reqMethod,urlText+item.params.reqApi);
  206. xhr.send(formData)
  207. }else{
  208. //链接直接跳转
  209. // window.open(item.name,'_blank ')
  210. //外部链接-暂定为获取当前大屏地址跳转
  211. window.open(localStorage.getItem('screenUrl') + '?identity=' + localStorage.getItem('identity'));
  212. }
  213. },
  214. // 当前激活的路由
  215. activeRoutes(key) {
  216. let self = this;
  217. var routes = [];
  218. if (this.childrenMenus && this.childrenMenus.length > 0) {
  219. this.childrenMenus.map((item) => {
  220. // if (key == item.parentPath || (key == "index" && "" == item.path)) {
  221. if (key == item.parentPath || (key == "index" && "" == item.path)) {
  222. routes.push(item);
  223. }
  224. });
  225. }
  226. if(routes.length > 0) {
  227. for(let i=0;i<self.topMenus.length;i++){
  228. if(key == self.topMenus[i].path){
  229. localStorage.setItem('leftRoutesName',self.topMenus[i].meta.title);
  230. }
  231. }
  232. localStorage.setItem('leftRoutesData',JSON.stringify(routes));
  233. if(routes[0].path != ''){
  234. this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
  235. }
  236. }else{
  237. store.dispatch('settings/setPageName', localStorage.getItem('leftRoutesName'))
  238. this.$store.commit("SET_SIDEBAR_ROUTERS", JSON.parse(localStorage.getItem('leftRoutesData')));
  239. }
  240. return routes;
  241. },
  242. ishttp(url) {
  243. return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
  244. }
  245. },
  246. };
  247. </script>
  248. <style lang="scss">
  249. .topmenu-container.el-menu--horizontal > .el-menu-item {
  250. float: left;
  251. height: 80px !important;
  252. line-height: 80px !important;
  253. color: #fff !important;
  254. padding: 0 5px !important;
  255. margin: 0 10px !important;
  256. }
  257. .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
  258. border-bottom: 2px solid #{'var(--theme)'} !important;
  259. color: #303133;
  260. }
  261. /* submenu item */
  262. .topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title {
  263. float: left;
  264. height: 50px !important;
  265. line-height: 50px !important;
  266. color: #999093 !important;
  267. padding: 0 5px !important;
  268. margin: 0 10px !important;
  269. }
  270. .top-submenu{
  271. .el-submenu__title i{
  272. color:#fff;
  273. }
  274. }
  275. </style>