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