index.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import './index.less';
  2. import { computed, defineComponent, ref, unref, watch, nextTick, CSSProperties } from 'vue';
  3. import { Layout } from 'ant-design-vue';
  4. import LayoutMenu from '../menu';
  5. import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  6. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  7. import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
  8. import { useTrigger, useDragLine, useSiderEvent } from './useLayoutSider';
  9. import { useLayoutContext } from '../useLayoutContext';
  10. export default defineComponent({
  11. name: 'LayoutSideBar',
  12. setup() {
  13. const topRef = ref(0);
  14. const dragBarRef = ref<ElRef>(null);
  15. const sideRef = ref<ElRef>(null);
  16. const {
  17. getCollapsed,
  18. getMenuWidth,
  19. getSplit,
  20. getMenuTheme,
  21. getRealWidth,
  22. getMenuHidden,
  23. getMenuFixed,
  24. } = useMenuSetting();
  25. const { getShowFullHeaderRef, getUnFixedAndFull } = useHeaderSetting();
  26. const injectValue = useLayoutContext();
  27. const { getTriggerAttr, getTriggerSlot } = useTrigger();
  28. const { renderDragLine } = useDragLine(sideRef, dragBarRef);
  29. const {
  30. getCollapsedWidth,
  31. onBreakpointChange,
  32. onCollapseChange,
  33. onSiderClick,
  34. } = useSiderEvent();
  35. const getMode = computed(() => {
  36. return unref(getSplit) ? MenuModeEnum.INLINE : null;
  37. });
  38. const getSplitType = computed(() => {
  39. return unref(getSplit) ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE;
  40. });
  41. const showClassSideBarRef = computed(() => {
  42. return unref(getSplit) ? unref(getMenuHidden) : true;
  43. });
  44. const getSiderClass = computed(() => {
  45. return {
  46. 'layout-sidebar': true,
  47. fixed: unref(getMenuFixed),
  48. hidden: !unref(showClassSideBarRef),
  49. };
  50. });
  51. const getSiderStyle = computed(() => {
  52. const top = `${unref(topRef)}px`;
  53. if (!unref(getMenuFixed)) {
  54. return { top };
  55. }
  56. return {
  57. top,
  58. height: `calc(100% - ${top})`,
  59. };
  60. });
  61. watch(
  62. () => getShowFullHeaderRef.value,
  63. () => {
  64. topRef.value = 0;
  65. if (unref(getUnFixedAndFull)) return;
  66. nextTick(() => {
  67. const fullHeaderEl = unref(injectValue.fullHeaderRef)?.$el;
  68. if (!fullHeaderEl) return;
  69. topRef.value = fullHeaderEl.offsetHeight;
  70. });
  71. },
  72. {
  73. immediate: true,
  74. }
  75. );
  76. const getHiddenDomStyle = computed(
  77. (): CSSProperties => {
  78. const width = `${unref(getRealWidth)}px`;
  79. return {
  80. width: width,
  81. overflow: 'hidden',
  82. flex: `0 0 ${width}`,
  83. maxWidth: width,
  84. minWidth: width,
  85. transition: 'all 0.2s',
  86. };
  87. }
  88. );
  89. function renderDefault() {
  90. return (
  91. <>
  92. <LayoutMenu
  93. theme={unref(getMenuTheme)}
  94. menuMode={unref(getMode)}
  95. splitType={unref(getSplitType)}
  96. />
  97. {renderDragLine()}
  98. </>
  99. );
  100. }
  101. return () => {
  102. return (
  103. <>
  104. {unref(getMenuFixed) && (
  105. <div style={unref(getHiddenDomStyle)} class={{ hidden: !unref(showClassSideBarRef) }} />
  106. )}
  107. <Layout.Sider
  108. ref={sideRef}
  109. breakpoint="md"
  110. collapsible
  111. class={unref(getSiderClass)}
  112. style={unref(getSiderStyle)}
  113. width={unref(getMenuWidth)}
  114. collapsed={unref(getCollapsed)}
  115. collapsedWidth={unref(getCollapsedWidth)}
  116. theme={unref(getMenuTheme)}
  117. onClick={onSiderClick}
  118. onCollapse={onCollapseChange}
  119. onBreakpoint={onBreakpointChange}
  120. {...unref(getTriggerAttr)}
  121. >
  122. {{
  123. ...unref(getTriggerSlot),
  124. default: () => renderDefault(),
  125. }}
  126. </Layout.Sider>
  127. </>
  128. );
  129. };
  130. },
  131. });