LayoutSideBar.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import { computed, defineComponent, nextTick, onMounted, ref, unref } from 'vue';
  2. import { Layout } from 'ant-design-vue';
  3. import SideBarTrigger from './SideBarTrigger';
  4. import { menuStore } from '/@/store/modules/menu';
  5. // import darkMiniIMg from '/@/assets/images/sidebar/dark-mini.png';
  6. // import lightMiniImg from '/@/assets/images/sidebar/light-mini.png';
  7. import darkImg from '/@/assets/images/sidebar/dark.png';
  8. // import lightImg from '/@/assets/images/sidebar/light.png';
  9. import { appStore } from '/@/store/modules/app';
  10. import { MenuModeEnum, MenuSplitTyeEnum, MenuThemeEnum } from '/@/enums/menuEnum';
  11. import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
  12. import { useDebounce } from '/@/hooks/core/useDebounce';
  13. import LayoutMenu from './LayoutMenu';
  14. export default defineComponent({
  15. name: 'DefaultLayoutSideBar',
  16. setup() {
  17. const initRef = ref(false);
  18. const brokenRef = ref(false);
  19. const collapseRef = ref(true);
  20. const dragBarRef = ref<Nullable<HTMLDivElement>>(null);
  21. const sideRef = ref<any>(null);
  22. const getProjectConfigRef = computed(() => {
  23. return appStore.getProjectConfig;
  24. });
  25. const getMiniWidth = computed(() => {
  26. const {
  27. menuSetting: { collapsedShowTitle },
  28. } = unref(getProjectConfigRef);
  29. return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
  30. });
  31. // 根据展开状态设置背景图片
  32. const getStyle = computed((): any => {
  33. // const collapse = unref(collapseRef);
  34. const theme = unref(getProjectConfigRef).menuSetting.theme;
  35. if (theme === MenuThemeEnum.LIGHT) {
  36. // bg = lightImg;
  37. return {};
  38. }
  39. let bg = '';
  40. if (theme === MenuThemeEnum.DARK) {
  41. // bg = collapse ? darkMiniIMg : darkImg;
  42. bg = darkImg;
  43. }
  44. return {
  45. 'background-image': `url(${bg})`,
  46. };
  47. });
  48. function onCollapseChange(val: boolean) {
  49. if (initRef.value) {
  50. collapseRef.value = val;
  51. menuStore.commitCollapsedState(val);
  52. } else {
  53. const collapsed = appStore.getProjectConfig.menuSetting.collapsed;
  54. !collapsed && menuStore.commitCollapsedState(val);
  55. }
  56. initRef.value = true;
  57. }
  58. // 菜单区域拖拽 - 鼠标移动
  59. function handleMouseMove(ele: any, wrap: any, clientX: number) {
  60. document.onmousemove = function (innerE) {
  61. let iT = ele.left + ((innerE || event).clientX - clientX);
  62. innerE = innerE || window.event;
  63. // let tarnameb = innerE.target || innerE.srcElement;
  64. const maxT = 600;
  65. const minT = unref(getMiniWidth);
  66. iT < 0 && (iT = 0);
  67. iT > maxT && (iT = maxT);
  68. iT < minT && (iT = minT);
  69. ele.style.left = wrap.style.width = iT + 'px';
  70. return false;
  71. };
  72. }
  73. // 菜单区域拖拽 - 鼠标松开
  74. function removeMouseup(ele: any) {
  75. const wrap = unref(sideRef).$el;
  76. document.onmouseup = function () {
  77. document.onmousemove = null;
  78. document.onmouseup = null;
  79. const width = parseInt(wrap.style.width);
  80. menuStore.commitDragStartState(false);
  81. if (!menuStore.getCollapsedState) {
  82. if (width > unref(getMiniWidth) + 20) {
  83. setMenuWidth(width);
  84. } else {
  85. menuStore.commitCollapsedState(true);
  86. }
  87. } else {
  88. if (width > unref(getMiniWidth)) {
  89. setMenuWidth(width);
  90. menuStore.commitCollapsedState(false);
  91. }
  92. }
  93. ele.releaseCapture && ele.releaseCapture();
  94. };
  95. }
  96. function setMenuWidth(width: number) {
  97. appStore.commitProjectConfigState({
  98. menuSetting: {
  99. menuWidth: width,
  100. },
  101. });
  102. }
  103. function changeWrapWidth() {
  104. const ele = unref(dragBarRef) as any;
  105. const side = unref(sideRef);
  106. const wrap = (side || {}).$el;
  107. // const eleWidth = 6;
  108. ele &&
  109. (ele.onmousedown = (e: any) => {
  110. menuStore.commitDragStartState(true);
  111. wrap.style.transition = 'unset';
  112. const clientX = (e || event).clientX;
  113. ele.left = ele.offsetLeft;
  114. handleMouseMove(ele, wrap, clientX);
  115. removeMouseup(ele);
  116. ele.setCapture && ele.setCapture();
  117. return false;
  118. });
  119. }
  120. function handleBreakpoint(broken: boolean) {
  121. brokenRef.value = broken;
  122. }
  123. onMounted(() => {
  124. nextTick(() => {
  125. const [exec] = useDebounce(changeWrapWidth, 20);
  126. exec();
  127. });
  128. });
  129. const getDragBarStyle = computed(() => {
  130. if (menuStore.getCollapsedState) {
  131. return { left: `${unref(getMiniWidth)}px` };
  132. }
  133. return {};
  134. });
  135. const getCollapsedWidth = computed(() => {
  136. return unref(brokenRef) ? 0 : unref(getMiniWidth);
  137. });
  138. function renderDragLine() {
  139. const { menuSetting: { hasDrag = true } = {} } = unref(getProjectConfigRef);
  140. return (
  141. <div
  142. class={[`layout-sidebar__dargbar`, !hasDrag ? 'hide' : '']}
  143. style={unref(getDragBarStyle)}
  144. ref={dragBarRef}
  145. />
  146. );
  147. }
  148. return () => {
  149. const {
  150. menuSetting: { theme, split: splitMenu },
  151. } = unref(getProjectConfigRef);
  152. const { getCollapsedState, getMenuWidthState } = menuStore;
  153. return (
  154. <Layout.Sider
  155. onCollapse={onCollapseChange}
  156. breakpoint="md"
  157. width={getMenuWidthState}
  158. collapsed={getCollapsedState}
  159. collapsible
  160. collapsedWidth={unref(getCollapsedWidth)}
  161. theme={theme}
  162. class="layout-sidebar"
  163. ref={sideRef}
  164. onBreakpoint={handleBreakpoint}
  165. style={unref(getStyle)}
  166. >
  167. {{
  168. trigger: () => <SideBarTrigger />,
  169. default: () => (
  170. <>
  171. <LayoutMenu
  172. theme={theme}
  173. menuMode={splitMenu ? MenuModeEnum.INLINE : null}
  174. splitType={splitMenu ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE}
  175. />
  176. {renderDragLine()}
  177. </>
  178. ),
  179. }}
  180. </Layout.Sider>
  181. );
  182. };
  183. },
  184. });