index.vue 7.3 KB

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