index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <ele-pro-layout
  3. :menus="menus"
  4. :tabs="theme.tabs"
  5. :showRefresh="false"
  6. :collapse="theme.collapse"
  7. :side-nav-collapse="theme.sideNavCollapse"
  8. :body-fullscreen="theme.bodyFullscreen"
  9. :show-tabs="theme.showTabs"
  10. :show-footer="theme.showFooter"
  11. :head-style="theme.headStyle"
  12. :side-style="theme.sideStyle"
  13. :layout-style="theme.layoutStyle"
  14. :side-menu-style="theme.sideMenuStyle"
  15. :tab-style="theme.tabStyle"
  16. :fixed-header="theme.fixedHeader"
  17. :fixed-sidebar="theme.fixedSidebar"
  18. :fixed-body="theme.fixedBody"
  19. :body-full="theme.bodyFull"
  20. :logo-auto-size="theme.logoAutoSize"
  21. :colorful-icon="theme.colorfulIcon"
  22. :side-unique-open="theme.sideUniqueOpen"
  23. :style-responsive="theme.styleResponsive"
  24. :project-name="projectName"
  25. :hide-footers="HIDE_FOOTERS"
  26. :hide-sidebars="HIDE_SIDEBARS"
  27. :repeatable-tabs="REPEATABLE_TABS"
  28. :home-title="HOME_TITLE || $t('layout.home')"
  29. :home-path="HOME_PATH"
  30. :layout-path="LAYOUT_PATH"
  31. :redirect-path="REDIRECT_PATH"
  32. :tab-sortable="true"
  33. :locale="locale"
  34. :i18n="i18n"
  35. @update:collapse="updateCollapse"
  36. @update:side-nav-collapse="updateSideNavCollapse"
  37. @update:body-fullscreen="updateBodyFullscreen"
  38. @tab-add="addPageTab"
  39. @tab-remove="removePageTab"
  40. @tab-remove-all="removeAllPageTab"
  41. @tab-remove-left="removeLeftPageTab"
  42. @tab-remove-right="removeRightPageTab"
  43. @tab-remove-other="removeOtherPageTab"
  44. @tabSortChange="setPageTabs"
  45. @reload-page="reloadPageTab"
  46. @logo-click="onLogoClick"
  47. @screen-size-change="screenSizeChange"
  48. @set-home-components="setHomeComponents"
  49. @tab-context-menu="onTabContextMenu"
  50. >
  51. <!-- 路由出口 -->
  52. <router-layout />
  53. <!-- logo 图标 -->
  54. <template v-slot:logo>
  55. <!-- <el-image v-if="logoImg" fit="contain" :src="logoImg" alt="logo" /> -->
  56. </template>
  57. <!-- 顶栏右侧区域 -->
  58. <template v-slot:right>
  59. <header-tools :fullscreen="fullscreen" @fullscreen="onFullscreen" />
  60. </template>
  61. <!-- 全局页脚 -->
  62. <!-- <template v-slot:footer>
  63. <page-footer />
  64. </template> -->
  65. <!-- 自定义菜单标题增加徽章、小红点 -->
  66. <template v-slot:title="{ title, item }">
  67. <span>{{ title }} </span>
  68. <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
  69. <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
  70. </div>
  71. </template>
  72. <template v-slot:top-title="{ title, item }">
  73. <span>{{ title }} </span>
  74. <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
  75. <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
  76. </div>
  77. </template>
  78. <template v-slot:nav-title="{ title, item }">
  79. <span>{{ title }} </span>
  80. <div v-if="item.meta && item.meta.badge" class="ele-menu-badge">
  81. <el-badge :value="item.meta.badge" :type="item.meta.badgeColor" />
  82. </div>
  83. </template>
  84. </ele-pro-layout>
  85. </template>
  86. <script>
  87. import { mapGetters } from 'vuex';
  88. import { toggleFullscreen, isFullscreen } from 'ele-admin';
  89. import RouterLayout from '@/components/RouterLayout/index.vue';
  90. import HeaderTools from './components/header-tools.vue';
  91. // import PageFooter from './components/page-footer.vue';
  92. import { getToken } from '@/utils/token-util';
  93. import { logoByCode } from '@/api/login/index';
  94. import {
  95. PROJECT_NAME,
  96. HIDE_SIDEBARS,
  97. HIDE_FOOTERS,
  98. REPEATABLE_TABS,
  99. HOME_TITLE,
  100. HOME_PATH,
  101. LAYOUT_PATH,
  102. REDIRECT_PATH,
  103. I18N_ENABLE
  104. } from '@/config/setting';
  105. import {
  106. addPageTab,
  107. removePageTab,
  108. removeAllPageTab,
  109. removeLeftPageTab,
  110. removeRightPageTab,
  111. removeOtherPageTab,
  112. reloadPageTab,
  113. setHomeComponents,
  114. setPageTabs
  115. } from '@/utils/page-tab-util';
  116. export default {
  117. name: 'EleLayout',
  118. components: {
  119. RouterLayout,
  120. HeaderTools
  121. // PageFooter
  122. },
  123. data() {
  124. return {
  125. // PROJECT_NAME,
  126. HIDE_SIDEBARS,
  127. HIDE_FOOTERS,
  128. REPEATABLE_TABS,
  129. HOME_PATH,
  130. HOME_TITLE,
  131. LAYOUT_PATH,
  132. REDIRECT_PATH,
  133. // 是否全屏
  134. fullscreen: false,
  135. logoImg: null,
  136. projectName: null
  137. };
  138. },
  139. computed: {
  140. // 当前语言
  141. locale() {
  142. return this.$i18n.locale;
  143. },
  144. // 菜单数据
  145. menus() {
  146. return this.$store.state.user.menus;
  147. },
  148. // 主题状态
  149. ...mapGetters(['theme'])
  150. },
  151. created() {
  152. if(getToken()){
  153. this.getLogo();
  154. }
  155. },
  156. methods: {
  157. getLogo() {
  158. logoByCode('logoCode').then((res) => {
  159. this.logoImg = res.logoUrl;
  160. this.projectName = res.logoName;
  161. });
  162. },
  163. /* 侧栏折叠切换 */
  164. updateCollapse(value) {
  165. // console.log('value:', this.$store.state.user.menus);
  166. this.$store.dispatch('theme/setCollapse', value);
  167. },
  168. /* 双侧栏一级折叠切换 */
  169. updateSideNavCollapse(value) {
  170. this.$store.dispatch('theme/setSideNavCollapse', value);
  171. },
  172. /* 内容区域全屏切换 */
  173. updateBodyFullscreen(value) {
  174. this.$store.dispatch('theme/setBodyFullscreen', value);
  175. },
  176. /* logo 点击事件 */
  177. onLogoClick(isHome) {
  178. isHome || this.$router.push(LAYOUT_PATH);
  179. },
  180. /* 监听屏幕尺寸改变 */
  181. screenSizeChange() {
  182. this.$store.dispatch('theme/updateScreenSize');
  183. this.fullscreen = isFullscreen();
  184. },
  185. /* 全屏切换 */
  186. onFullscreen() {
  187. try {
  188. this.fullscreen = toggleFullscreen();
  189. } catch (e) {
  190. this.$message.error('您的浏览器不支持全屏模式');
  191. }
  192. },
  193. /* 页签右键菜单点击事件 */
  194. onTabContextMenu({ key, tabKey, item, active }) {
  195. switch (key) {
  196. case 'reload': // 刷新
  197. reloadPageTab({
  198. isHome: !item,
  199. fullPath: item?.fullPath ?? tabKey
  200. });
  201. break;
  202. case 'close': // 关闭当前
  203. removePageTab({
  204. key: item?.fullPath ?? tabKey,
  205. active
  206. });
  207. break;
  208. case 'left': // 关闭左侧
  209. removeLeftPageTab({
  210. key: tabKey,
  211. active
  212. });
  213. break;
  214. case 'right': // 关闭右侧
  215. removeRightPageTab({
  216. key: tabKey,
  217. active
  218. });
  219. break;
  220. case 'other': // 关闭其他
  221. removeOtherPageTab({
  222. key: tabKey,
  223. active
  224. });
  225. break;
  226. }
  227. },
  228. /* 菜单标题国际化 */
  229. i18n(_path, key) {
  230. if (!I18N_ENABLE || !key) {
  231. return;
  232. }
  233. const k = 'route.' + key + '._name';
  234. const title = this.$t(k);
  235. if (title !== k) {
  236. return title;
  237. }
  238. },
  239. //
  240. addPageTab,
  241. removePageTab,
  242. removeAllPageTab,
  243. removeLeftPageTab,
  244. removeRightPageTab,
  245. removeOtherPageTab,
  246. reloadPageTab,
  247. setHomeComponents,
  248. setPageTabs
  249. }
  250. };
  251. </script>
  252. <style lang="scss">
  253. .ele-admin-layout {
  254. .ele-admin-logo {
  255. font-size: 18px !important;
  256. img {
  257. width: 50px !important;
  258. height: auto !important;
  259. }
  260. }
  261. }
  262. // 侧栏菜单徽章样式,定位在右侧垂直居中并调小尺寸
  263. .ele-menu-badge {
  264. position: absolute;
  265. top: 50%;
  266. right: 14px;
  267. line-height: 1;
  268. margin-top: -9px;
  269. font-size: 0;
  270. .el-badge__content {
  271. height: 18px;
  272. line-height: 18px;
  273. border-radius: 9px;
  274. border: none;
  275. min-width: 18px;
  276. padding: 0 4px;
  277. box-sizing: border-box;
  278. }
  279. }
  280. // 父级菜单标题中右侧多定位一点,避免与箭头重合
  281. .el-submenu > .el-submenu__title .ele-menu-badge {
  282. right: 36px;
  283. }
  284. // 折叠悬浮中样式调整
  285. .el-menu--popup {
  286. .el-submenu > .el-submenu__title .ele-menu-badge {
  287. right: 20px;
  288. }
  289. }
  290. // 侧栏折叠后样式调整
  291. .ele-admin-collapse .ele-admin-sidebar-menus > .el-scrollbar {
  292. & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
  293. & > .el-menu-item,
  294. & > .el-submenu > .el-submenu__title {
  295. .ele-menu-badge {
  296. top: 2px;
  297. right: 2px;
  298. margin: 0;
  299. }
  300. }
  301. }
  302. }
  303. // 顶栏菜单标题中样式调整
  304. .ele-admin-header-nav > .el-scrollbar > .el-scrollbar__wrap {
  305. & > .el-scrollbar__view > .el-menu {
  306. & > .el-menu-item,
  307. & > .el-submenu > .el-submenu__title {
  308. .ele-menu-badge {
  309. position: static;
  310. right: auto;
  311. top: auto;
  312. display: inline-block;
  313. vertical-align: 6px;
  314. margin: 0 0 0 2px;
  315. }
  316. }
  317. }
  318. }
  319. // 双侧栏时一级侧栏菜单中样式调整,定位在右上角
  320. .ele-admin-sidebar-nav-menu > .el-scrollbar > .el-scrollbar__wrap {
  321. & > .el-scrollbar__view > .el-menu {
  322. & > .el-menu-item,
  323. & > .el-submenu > .el-submenu__title {
  324. .ele-menu-badge {
  325. top: 0;
  326. right: 0;
  327. margin: 0;
  328. }
  329. }
  330. }
  331. }
  332. // 双侧栏时一级侧栏菜单折叠后样式调整
  333. .ele-admin-nav-collapse .ele-admin-sidebar-nav-menu > .el-scrollbar {
  334. & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
  335. & > .el-menu-item,
  336. & > .el-submenu > .el-submenu__title {
  337. .ele-menu-badge {
  338. top: 0;
  339. right: 0;
  340. }
  341. }
  342. }
  343. }
  344. .ele-admin-layout .ele-admin-logo img {
  345. height: auto !important;
  346. width: 80px !important;
  347. margin-right: 5px;
  348. max-height: 35px;
  349. }
  350. </style>