AppLayout.vue 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <script setup>
  2. import { ref, computed } from "vue";
  3. import AppTopBar from "@/components/AppTopBar.vue";
  4. import AppSidebar from "@/components/AppSidebar.vue";
  5. import AppFooter from "@/components/AppFooter.vue";
  6. import AppMessage from "@/components/AppMessage.vue";
  7. import menu from "@/utils/menu";
  8. import menuAdmin from "@/utils/menu_admin";
  9. const containerClass = computed(() => {
  10. return [
  11. "layout-wrapper",
  12. "layout-static",
  13. {
  14. "layout-static-sidebar-inactive": staticMenuInactive.value,
  15. "layout-mobile-sidebar-active": mobileMenuActive.value,
  16. },
  17. ];
  18. });
  19. const mobileMenuActive = ref(false);
  20. const staticMenuInactive = ref(false);
  21. const menuClick = ref(false);
  22. const isDesktop = () => window.innerWidth >= 992;
  23. const onMenuToggle = () => {
  24. menuClick.value = true;
  25. if (isDesktop()) {
  26. staticMenuInactive.value = !staticMenuInactive.value;
  27. } else {
  28. mobileMenuActive.value = !mobileMenuActive.value;
  29. }
  30. };
  31. const onWrapperClick = () => {
  32. if (!menuClick.value) {
  33. mobileMenuActive.value = false;
  34. }
  35. menuClick.value = false;
  36. };
  37. </script>
  38. <template>
  39. <div :class="containerClass" @click="onWrapperClick">
  40. <AppTopBar @menu-toggle="onMenuToggle" />
  41. <div class="layout-sidebar">
  42. <AppSidebar :model="$page.props.isAdmin ? menuAdmin : menu" />
  43. </div>
  44. <div class="layout-main-container">
  45. <div class="layout-main">
  46. <AppMessage />
  47. <slot />
  48. </div>
  49. <AppFooter />
  50. </div>
  51. <Transition name="layout-mask">
  52. <div
  53. class="layout-mask p-component-overlay"
  54. v-if="mobileMenuActive"
  55. ></div>
  56. </Transition>
  57. </div>
  58. </template>