index.vue 2.9 KB

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