AdminLayout.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <a-layout :class="['admin-layout', 'beauty-scroll']">
  3. <drawer v-if="isMobile" v-model="drawerOpen">
  4. <side-menu
  5. :theme="theme.mode"
  6. :menuData="menuData"
  7. :collapsed="false"
  8. :collapsible="false"
  9. @menuSelect="onMenuSelect"
  10. />
  11. </drawer>
  12. <side-menu
  13. :class="[fixedSideBar ? 'fixed-side' : '']"
  14. :theme="theme.mode"
  15. v-else-if="layout === 'side' || layout === 'mix'"
  16. :menuData="sideMenuData"
  17. :collapsed="collapsed"
  18. :collapsible="true"
  19. />
  20. <div
  21. v-if="fixedSideBar && !isMobile"
  22. :style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`"
  23. class="virtual-side"
  24. ></div>
  25. <drawer v-if="!hideSetting" v-model="showSetting" placement="right">
  26. <div class="setting" slot="handler">
  27. <a-icon :type="showSetting ? 'close' : 'setting'" />
  28. </div>
  29. <setting />
  30. </drawer>
  31. <a-layout class="admin-layout-main beauty-scroll">
  32. <admin-header
  33. :class="[
  34. {
  35. 'fixed-tabs': fixedTabs,
  36. 'fixed-header': fixedHeader,
  37. 'multi-page': multiPage,
  38. },
  39. ]"
  40. :style="headerStyle"
  41. :menuData="headMenuData"
  42. :collapsed="collapsed"
  43. @toggleCollapse="toggleCollapse"
  44. />
  45. <!-- <a-layout-header :class="['virtual-header', {'fixed-tabs' : fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]" v-show="fixedHeader"></a-layout-header> -->
  46. <a-layout-content
  47. class="admin-layout-content"
  48. :style="`min-height: ${minHeight}px;`"
  49. >
  50. <div style="position: relative" class="admin-layout-content-subject">
  51. <slot></slot>
  52. </div>
  53. </a-layout-content>
  54. <!-- <a-layout-footer style="padding: 0px">
  55. <page-footer :link-list="footerLinks" :copyright="copyright" />
  56. </a-layout-footer> -->
  57. </a-layout>
  58. </a-layout>
  59. </template>
  60. <script>
  61. import AdminHeader from "./header/AdminHeader";
  62. // import PageFooter from './footer/PageFooter'
  63. import Drawer from "../components/tool/Drawer";
  64. import SideMenu from "../components/menu/SideMenu";
  65. import Setting from "../components/setting/Setting";
  66. import { mapState, mapMutations, mapGetters } from "vuex";
  67. // const minHeight = window.innerHeight - 64 - 122
  68. export default {
  69. name: "AdminLayout",
  70. components: { Setting, SideMenu, Drawer, AdminHeader },
  71. data() {
  72. return {
  73. minHeight: window.innerHeight - 64 - 122,
  74. collapsed: false,
  75. showSetting: false,
  76. drawerOpen: false,
  77. };
  78. },
  79. provide() {
  80. return {
  81. adminLayout: this,
  82. };
  83. },
  84. watch: {
  85. $route(val) {
  86. this.setActivated(val);
  87. },
  88. layout() {
  89. this.setActivated(this.$route);
  90. },
  91. isMobile(val) {
  92. if (!val) {
  93. this.drawerOpen = false;
  94. }
  95. },
  96. },
  97. computed: {
  98. ...mapState("setting", [
  99. "isMobile",
  100. "theme",
  101. "layout",
  102. "footerLinks",
  103. "copyright",
  104. "fixedHeader",
  105. "fixedSideBar",
  106. "fixedTabs",
  107. "hideSetting",
  108. "multiPage",
  109. ]),
  110. ...mapGetters("setting", ["firstMenu", "subMenu", "menuData"]),
  111. sideMenuWidth() {
  112. return this.collapsed ? "80px" : "256px";
  113. },
  114. headerStyle() {
  115. let width =
  116. this.fixedHeader && this.layout !== "head" && !this.isMobile
  117. ? `calc(100% - ${this.sideMenuWidth})`
  118. : "100%";
  119. let position = this.fixedHeader ? "fixed" : "static";
  120. // console.log(width);
  121. // console.log(position);
  122. return `width: ${width}; position: ${position};`;
  123. },
  124. headMenuData() {
  125. const { layout, menuData, firstMenu } = this;
  126. return layout === "mix" ? firstMenu : menuData;
  127. },
  128. sideMenuData() {
  129. const { layout, menuData, subMenu } = this;
  130. console.log(menuData, 666, this);
  131. return layout === "mix" ? subMenu : menuData;
  132. },
  133. },
  134. methods: {
  135. ...mapMutations("setting", ["correctPageMinHeight", "setActivatedFirst"]),
  136. toggleCollapse() {
  137. this.collapsed = !this.collapsed;
  138. },
  139. onMenuSelect() {
  140. this.toggleCollapse();
  141. },
  142. setActivated(route) {
  143. if (this.layout === "mix") {
  144. let matched = route.matched;
  145. matched = matched.slice(0, matched.length - 1);
  146. const { firstMenu } = this;
  147. for (let menu of firstMenu) {
  148. if (matched.findIndex((item) => item.path === menu.fullPath) !== -1) {
  149. this.setActivatedFirst(menu.fullPath);
  150. break;
  151. }
  152. }
  153. }
  154. },
  155. },
  156. created() {
  157. this.correctPageMinHeight(this.minHeight - 24);
  158. this.setActivated(this.$route);
  159. },
  160. beforeDestroy() {
  161. this.correctPageMinHeight(-this.minHeight + 24);
  162. },
  163. };
  164. </script>
  165. <style lang="less" scoped>
  166. .admin-layout {
  167. height: 100%;
  168. .side-menu {
  169. &.fixed-side {
  170. position: fixed;
  171. height: 100vh;
  172. left: 0;
  173. top: 0;
  174. }
  175. }
  176. .virtual-side {
  177. transition: all 0.2s;
  178. }
  179. .virtual-header {
  180. transition: all 0.2s;
  181. opacity: 0;
  182. &.fixed-tabs.multi-page:not(.fixed-header) {
  183. height: 0;
  184. }
  185. }
  186. .admin-layout-main {
  187. // min-height: 100vh;
  188. height: 100%;
  189. .admin-header {
  190. top: 0;
  191. right: 0;
  192. overflow: hidden;
  193. transition: all 0.2s;
  194. &.fixed-tabs.multi-page:not(.fixed-header) {
  195. height: 0;
  196. }
  197. }
  198. }
  199. .admin-layout-content {
  200. padding: 24px 24px 0;
  201. box-sizing: border-box;
  202. // background: #fff;
  203. /*overflow-x: hidden;*/
  204. /*min-height: calc(100vh - 64px - 122px);*/
  205. .admin-layout-content-subject {
  206. height: 100%;
  207. padding-top: 24px;
  208. box-sizing: border-box;
  209. }
  210. }
  211. .setting {
  212. background-color: @primary-color;
  213. color: @base-bg-color;
  214. border-radius: 5px 0 0 5px;
  215. line-height: 40px;
  216. font-size: 22px;
  217. width: 40px;
  218. height: 40px;
  219. box-shadow: -2px 0 8px @shadow-color;
  220. }
  221. }
  222. </style>