index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <template>
  2. <div class="vue-admin-beautiful-wrapper" :class="classObj">
  3. <div
  4. v-if="'horizontal' === layout"
  5. class="layout-container-horizontal"
  6. :class="{
  7. fixed: header === 'fixed',
  8. 'no-tags-bar': tagsBar === 'false' || tagsBar === false,
  9. }"
  10. >
  11. <div :class="header === 'fixed' ? 'fixed-header' : ''">
  12. <top-bar></top-bar>
  13. <div
  14. v-if="tagsBar === 'true' || tagsBar === true"
  15. :class="{ 'tag-view-show': tagsBar }"
  16. >
  17. <div class="vab-main">
  18. <tags-bar></tags-bar>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="vab-main main-padding">
  23. <ad></ad>
  24. <app-main></app-main>
  25. </div>
  26. </div>
  27. <div
  28. v-else
  29. class="layout-container-vertical"
  30. :class="{
  31. fixed: header === 'fixed',
  32. 'no-tags-bar': tagsBar === 'false' || tagsBar === false,
  33. }"
  34. >
  35. <div
  36. v-if="device === 'mobile' && collapse === false"
  37. class="mask"
  38. @click="handleFoldSideBar"
  39. />
  40. <side-bar></side-bar>
  41. <div class="vab-main" :class="collapse ? 'is-collapse-main' : ''">
  42. <div :class="header === 'fixed' ? 'fixed-header' : ''">
  43. <nav-bar></nav-bar>
  44. <tags-bar v-if="tagsBar === 'true' || tagsBar === true" />
  45. </div>
  46. <ad></ad>
  47. <app-main></app-main>
  48. </div>
  49. </div>
  50. <el-backtop></el-backtop>
  51. </div>
  52. </template>
  53. <script>
  54. import { Ad, AppMain, NavBar, SideBar, TagsBar, TopBar } from "./components";
  55. import { mapActions, mapGetters } from "vuex";
  56. import { tokenName } from "@/config/settings";
  57. export default {
  58. name: "Layout",
  59. components: {
  60. Ad,
  61. TopBar,
  62. NavBar,
  63. SideBar,
  64. AppMain,
  65. TagsBar,
  66. },
  67. data() {
  68. return { oldLayout: "" };
  69. },
  70. computed: {
  71. ...mapGetters({
  72. layout: "settings/layout",
  73. tagsBar: "settings/tagsBar",
  74. collapse: "settings/collapse",
  75. header: "settings/header",
  76. device: "settings/device",
  77. }),
  78. classObj() {
  79. return {
  80. mobile: this.device === "mobile",
  81. };
  82. },
  83. },
  84. beforeMount() {
  85. window.addEventListener("resize", this.handleResize);
  86. },
  87. beforeDestroy() {
  88. window.removeEventListener("resize", this.handleResize);
  89. },
  90. mounted() {
  91. this.oldLayout = this.layout;
  92. const userAgent = navigator.userAgent;
  93. if (userAgent.includes("Juejin")) {
  94. this.$baseAlert(
  95. "vue-admin-beautiful不支持在掘金内置浏览器演示,请手动复制以下地址到浏览器中查看http://mpfhrd48.sanxing.uz7.cn/vue-admin-beautiful"
  96. );
  97. }
  98. const isMobile = this.handleIsMobile();
  99. if (isMobile) {
  100. if (isMobile) {
  101. //横向布局时如果是手机端访问那么改成纵向版
  102. this.$store.dispatch("settings/changeLayout", "vertical");
  103. } else {
  104. this.$store.dispatch("settings/changeLayout", this.oldLayout);
  105. }
  106. this.$store.dispatch("settings/toggleDevice", "mobile");
  107. setTimeout(() => {
  108. this.$store.dispatch("settings/foldSideBar");
  109. }, 2000);
  110. } else {
  111. this.$store.dispatch("settings/openSideBar");
  112. }
  113. this.$nextTick(() => {
  114. window.addEventListener(
  115. "storage",
  116. (e) => {
  117. if (e.key === tokenName || e.key === null) window.location.reload();
  118. if (e.key === tokenName && e.value === null)
  119. window.location.reload();
  120. },
  121. false
  122. );
  123. });
  124. },
  125. methods: {
  126. ...mapActions({
  127. handleFoldSideBar: "settings/foldSideBar",
  128. }),
  129. handleIsMobile() {
  130. return document.body.getBoundingClientRect().width - 1 < 992;
  131. },
  132. handleResize() {
  133. if (!document.hidden) {
  134. const isMobile = this.handleIsMobile();
  135. if (isMobile) {
  136. //横向布局时如果是手机端访问那么改成纵向版
  137. this.$store.dispatch("settings/changeLayout", "vertical");
  138. } else {
  139. this.$store.dispatch("settings/changeLayout", this.oldLayout);
  140. }
  141. this.$store.dispatch(
  142. "settings/toggleDevice",
  143. isMobile ? "mobile" : "desktop"
  144. );
  145. }
  146. },
  147. },
  148. };
  149. </script>
  150. <style lang="scss" scoped>
  151. @mixin fix-header {
  152. position: fixed;
  153. top: 0;
  154. right: 0;
  155. left: 0;
  156. z-index: $base-z-index - 2;
  157. width: 100%;
  158. overflow: hidden;
  159. }
  160. .vue-admin-beautiful-wrapper {
  161. position: relative;
  162. width: 100%;
  163. height: 100%;
  164. .layout-container-horizontal {
  165. position: relative;
  166. &.fixed {
  167. padding-top: calc(#{$base-top-bar-height} + #{$base-tags-bar-height});
  168. }
  169. &.fixed.no-tags-bar {
  170. padding-top: $base-top-bar-height;
  171. }
  172. ::v-deep {
  173. .vab-main {
  174. width: 88%;
  175. margin: auto;
  176. }
  177. .fixed-header {
  178. @include fix-header;
  179. }
  180. .tag-view-show {
  181. background: $base-color-white;
  182. box-shadow: $base-box-shadow;
  183. }
  184. .nav-bar-container {
  185. .fold-unfold {
  186. display: none;
  187. }
  188. }
  189. .main-padding {
  190. .app-main-container {
  191. margin-top: $base-padding;
  192. margin-bottom: $base-padding;
  193. background: $base-color-white;
  194. }
  195. }
  196. }
  197. }
  198. .layout-container-vertical {
  199. position: relative;
  200. .mask {
  201. position: fixed;
  202. top: 0;
  203. right: 0;
  204. bottom: 0;
  205. left: 0;
  206. z-index: $base-z-index - 1;
  207. width: 100%;
  208. height: 100vh;
  209. overflow: hidden;
  210. background: #000;
  211. opacity: 0.5;
  212. }
  213. &.fixed {
  214. padding-top: calc(#{$base-nav-bar-height} + #{$base-tags-bar-height});
  215. }
  216. &.fixed.no-tags-bar {
  217. padding-top: $base-nav-bar-height;
  218. }
  219. .vab-main {
  220. position: relative;
  221. min-height: 100%;
  222. margin-left: $base-left-menu-width;
  223. background: #f6f8f9;
  224. transition: $base-transition;
  225. ::v-deep {
  226. .fixed-header {
  227. @include fix-header;
  228. left: $base-left-menu-width;
  229. width: $base-right-content-width;
  230. box-shadow: $base-box-shadow;
  231. transition: $base-transition;
  232. }
  233. .nav-bar-container {
  234. position: relative;
  235. box-sizing: border-box;
  236. }
  237. .tags-bar-container {
  238. box-sizing: border-box;
  239. }
  240. .app-main-container {
  241. width: calc(100% - #{$base-padding} - #{$base-padding});
  242. margin: $base-padding auto;
  243. background: $base-color-white;
  244. border-radius: $base-border-radius;
  245. }
  246. }
  247. &.is-collapse-main {
  248. margin-left: $base-left-menu-width-min;
  249. ::v-deep {
  250. .fixed-header {
  251. left: $base-left-menu-width-min;
  252. width: calc(100% - 65px);
  253. }
  254. }
  255. }
  256. }
  257. }
  258. /* 手机端开始 */
  259. &.mobile {
  260. ::v-deep {
  261. .el-pager,
  262. .el-pagination__jump {
  263. display: none;
  264. }
  265. .layout-container-vertical {
  266. .el-scrollbar.side-bar-container.is-collapse {
  267. width: 0;
  268. }
  269. .vab-main {
  270. width: 100%;
  271. margin-left: 0;
  272. }
  273. }
  274. .vab-main {
  275. .fixed-header {
  276. left: 0 !important;
  277. width: 100% !important;
  278. }
  279. }
  280. }
  281. }
  282. /* 手机端结束 */
  283. }
  284. </style>