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