Newer
Older
DH_Apicture / src / layout / index.vue
@zhangqy zhangqy on 29 Nov 3 KB first commit
  1. <template>
  2. <!-- 部分全屏页面 -->
  3. <app-main v-if="FullScreen" />
  4. <div v-else :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
  5. <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
  6. <sidebar v-if="!sidebar.hide" class="sidebar-container" />
  7. <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
  8. <div :class="{ 'fixed-header': fixedHeader }">
  9. <navbar @setLayout="setLayout" />
  10. <tags-view v-if="needTagsView" />
  11. </div>
  12. <app-main />
  13. <settings ref="settingRef" />
  14. </div>
  15. </div>
  16. </template>
  17.  
  18. <script setup>
  19. import { useWindowSize } from '@vueuse/core';
  20. import Sidebar from './components/Sidebar/index.vue';
  21. import { AppMain, Navbar, Settings, TagsView } from './components';
  22. import defaultSettings from '@/settings';
  23.  
  24. import useAppStore from '@/store/modules/app';
  25. import useSettingsStore from '@/store/modules/settings';
  26. import { useRouter } from 'vue-router';
  27. import { ref } from 'vue';
  28. const router = useRouter();
  29. const settingsStore = useSettingsStore();
  30. const theme = computed(() => settingsStore.theme);
  31. const sideTheme = computed(() => settingsStore.sideTheme);
  32. const sidebar = computed(() => useAppStore().sidebar);
  33. const device = computed(() => useAppStore().device);
  34. const needTagsView = computed(() => settingsStore.tagsView);
  35. const fixedHeader = computed(() => settingsStore.fixedHeader);
  36.  
  37. const classObj = computed(() => ({
  38. hideSidebar: !sidebar.value.opened,
  39. openSidebar: sidebar.value.opened,
  40. withoutAnimation: sidebar.value.withoutAnimation,
  41. mobile: device.value === 'mobile',
  42. }));
  43.  
  44. const { width, height } = useWindowSize();
  45. const WIDTH = 992; // refer to Bootstrap's responsive design
  46.  
  47. watchEffect(() => {
  48. if (device.value === 'mobile' && sidebar.value.opened) {
  49. useAppStore().closeSideBar({ withoutAnimation: false });
  50. }
  51. if (width.value - 1 < WIDTH) {
  52. useAppStore().toggleDevice('mobile');
  53. useAppStore().closeSideBar({ withoutAnimation: true });
  54. } else {
  55. useAppStore().toggleDevice('desktop');
  56. }
  57. });
  58.  
  59. function handleClickOutside() {
  60. useAppStore().closeSideBar({ withoutAnimation: false });
  61. }
  62.  
  63. const settingRef = ref(null);
  64. function setLayout() {
  65. settingRef.value.openSetting();
  66. }
  67. const FullScreen = ref(false);
  68. watch(
  69. () => router.currentRoute.value.path,
  70. (newValue, oldValue) => {
  71. console.log('watch路由变化', newValue, router.currentRoute.value.query.type);
  72. if (router.currentRoute.value.query.type == 'FullScreen') {
  73. // 全屏页面
  74. FullScreen.value = true;
  75. } else {
  76. // 非全屏页面
  77. FullScreen.value = false;
  78. }
  79. },
  80. { immediate: true }
  81. );
  82. </script>
  83.  
  84. <style lang="scss" scoped>
  85. @import '@/assets/styles/mixin.scss';
  86. @import '@/assets/styles/variables.module.scss';
  87.  
  88. .app-wrapper {
  89. @include clearfix;
  90. position: relative;
  91. height: 100%;
  92. width: 100%;
  93.  
  94. &.mobile.openSidebar {
  95. position: fixed;
  96. top: 0;
  97. }
  98. }
  99.  
  100. .drawer-bg {
  101. background: #000;
  102. opacity: 0.3;
  103. width: 100%;
  104. top: 0;
  105. height: 100%;
  106. position: absolute;
  107. z-index: 999;
  108. }
  109.  
  110. .fixed-header {
  111. position: fixed;
  112. top: 0;
  113. right: 0;
  114. z-index: 9;
  115. width: calc(100% - #{$base-sidebar-width});
  116. transition: width 0.28s;
  117. }
  118.  
  119. .hideSidebar .fixed-header {
  120. width: calc(100% - 54px);
  121. }
  122.  
  123. .sidebarHide .fixed-header {
  124. width: 100%;
  125. }
  126.  
  127. .mobile .fixed-header {
  128. width: 100%;
  129. }
  130. </style>