layout-header.vue 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <script setup lang="ts">
  2. import type { CSSProperties } from 'vue';
  3. import { computed, useSlots } from 'vue';
  4. import { Menu } from '@vben-core/icons';
  5. import { VbenIconButton } from '@vben-core/shadcn-ui';
  6. interface Props {
  7. /**
  8. * 横屏
  9. */
  10. fullWidth: boolean;
  11. /**
  12. * 高度
  13. */
  14. height: number;
  15. /**
  16. * 是否混合导航
  17. * @default false
  18. */
  19. isMixedNav: boolean;
  20. /**
  21. * 是否移动端
  22. */
  23. isMobile: boolean;
  24. /**
  25. * 是否显示
  26. */
  27. show: boolean;
  28. /**
  29. * 是否显示关闭菜单按钮
  30. */
  31. showToggleBtn: boolean;
  32. /**
  33. * 侧边菜单宽度
  34. */
  35. sidebarWidth: number;
  36. /**
  37. * 宽度
  38. */
  39. width: string;
  40. /**
  41. * zIndex
  42. */
  43. zIndex: number;
  44. }
  45. const props = withDefaults(defineProps<Props>(), {});
  46. const emit = defineEmits<{ openMenu: []; toggleSidebar: [] }>();
  47. const slots = useSlots();
  48. const style = computed((): CSSProperties => {
  49. const { fullWidth, height, show } = props;
  50. const right = !show || !fullWidth ? undefined : 0;
  51. return {
  52. height: `${height}px`,
  53. marginTop: show ? 0 : `-${height}px`,
  54. right,
  55. };
  56. });
  57. const logoStyle = computed((): CSSProperties => {
  58. return {
  59. minWidth: `${props.isMobile ? 40 : props.sidebarWidth}px`,
  60. };
  61. });
  62. function handleToggleMenu() {
  63. props.isMobile ? emit('openMenu') : emit('toggleSidebar');
  64. }
  65. </script>
  66. <template>
  67. <header
  68. :style="style"
  69. class="border-border bg-background top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
  70. >
  71. <div v-if="slots.logo" :style="logoStyle">
  72. <slot name="logo"></slot>
  73. </div>
  74. <VbenIconButton
  75. v-if="showToggleBtn || isMobile"
  76. class="my-0 ml-2 mr-1 rounded"
  77. @click="handleToggleMenu"
  78. >
  79. <Menu class="size-4" />
  80. </VbenIconButton>
  81. <slot></slot>
  82. </header>
  83. </template>