mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 14:13:40 +08:00
wip: refactor layout
This commit is contained in:
77
src/layouts/default/sider/LayoutSideBar.tsx
Normal file
77
src/layouts/default/sider/LayoutSideBar.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import './index.less';
|
||||
|
||||
import { computed, defineComponent, ref, unref } from 'vue';
|
||||
|
||||
import { Layout } from 'ant-design-vue';
|
||||
import LayoutMenu from '/@/layouts/default/menu/LayoutMenu';
|
||||
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useTrigger, useDragLine, useSiderEvent } from './useLayoutSider';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LayoutSideBar',
|
||||
setup() {
|
||||
const dragBarRef = ref<Nullable<HTMLDivElement>>(null);
|
||||
const sideRef = ref<Nullable<HTMLDivElement>>(null);
|
||||
|
||||
const { getCollapsed, getMenuWidth, getSplit, getTheme } = useMenuSetting();
|
||||
|
||||
const { getTriggerAttr, getTriggerSlot } = useTrigger();
|
||||
|
||||
const { renderDragLine } = useDragLine(sideRef, dragBarRef);
|
||||
|
||||
const {
|
||||
getCollapsedWidth,
|
||||
onBreakpointChange,
|
||||
onCollapseChange,
|
||||
onSiderClick,
|
||||
} = useSiderEvent();
|
||||
|
||||
const getMode = computed(() => {
|
||||
return unref(getSplit) ? MenuModeEnum.INLINE : null;
|
||||
});
|
||||
|
||||
const getSplitType = computed(() => {
|
||||
return unref(getSplit) ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE;
|
||||
});
|
||||
|
||||
function renderDefault() {
|
||||
return (
|
||||
<>
|
||||
<LayoutMenu
|
||||
theme={unref(getTheme)}
|
||||
menuMode={unref(getMode)}
|
||||
splitType={unref(getSplitType)}
|
||||
/>
|
||||
{renderDragLine()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<Layout.Sider
|
||||
ref={sideRef}
|
||||
class="layout-sidebar"
|
||||
breakpoint="md"
|
||||
collapsible
|
||||
width={unref(getMenuWidth)}
|
||||
collapsed={unref(getCollapsed)}
|
||||
collapsedWidth={unref(getCollapsedWidth)}
|
||||
theme={unref(getTheme)}
|
||||
onClick={onSiderClick}
|
||||
onCollapse={onCollapseChange}
|
||||
onBreakpoint={onBreakpointChange}
|
||||
{...unref(getTriggerAttr)}
|
||||
>
|
||||
{{
|
||||
...unref(getTriggerSlot),
|
||||
default: () => renderDefault(),
|
||||
}}
|
||||
</Layout.Sider>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
44
src/layouts/default/sider/index.less
Normal file
44
src/layouts/default/sider/index.less
Normal file
@@ -0,0 +1,44 @@
|
||||
@import (reference) '../../../design/index.less';
|
||||
|
||||
.layout-sidebar {
|
||||
background-size: 100% 100%;
|
||||
|
||||
&.ant-layout-sider-dark {
|
||||
background: @sider-dark-bg-color;
|
||||
}
|
||||
|
||||
&:not(.ant-layout-sider-dark) {
|
||||
border-right: 1px solid @border-color-light;
|
||||
}
|
||||
|
||||
.ant-layout-sider-zero-width-trigger {
|
||||
top: 40%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&__darg-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
z-index: @side-drag-z-index;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
cursor: col-resize;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: @primary-color;
|
||||
box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout-sider-trigger {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
163
src/layouts/default/sider/useLayoutSider.tsx
Normal file
163
src/layouts/default/sider/useLayoutSider.tsx
Normal file
@@ -0,0 +1,163 @@
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { computed, unref, onMounted, nextTick, ref } from 'vue';
|
||||
import LayoutTrigger from '/@/layouts/default/LayoutTrigger';
|
||||
|
||||
import { TriggerEnum } from '/@/enums/menuEnum';
|
||||
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
||||
|
||||
/**
|
||||
* Handle related operations of menu events
|
||||
*/
|
||||
export function useSiderEvent() {
|
||||
const initRef = ref(false);
|
||||
const brokenRef = ref(false);
|
||||
const collapseRef = ref(true);
|
||||
|
||||
const { setMenuSetting, getCollapsed, getMiniWidthNumber, getShow } = useMenuSetting();
|
||||
|
||||
const getCollapsedWidth = computed(() => {
|
||||
return unref(brokenRef) ? 0 : unref(getMiniWidthNumber);
|
||||
});
|
||||
|
||||
function onCollapseChange(val: boolean) {
|
||||
if (initRef.value) {
|
||||
collapseRef.value = val;
|
||||
setMenuSetting({ collapsed: val });
|
||||
} else {
|
||||
!unref(getCollapsed) && setMenuSetting({ collapsed: val });
|
||||
}
|
||||
initRef.value = true;
|
||||
}
|
||||
|
||||
function onBreakpointChange(broken: boolean) {
|
||||
brokenRef.value = broken;
|
||||
}
|
||||
|
||||
function onSiderClick(e: ChangeEvent) {
|
||||
if (!e || !e.target || e.target.className !== 'basic-menu__content') return;
|
||||
if (!unref(getCollapsed) || !unref(getShow)) return;
|
||||
setMenuSetting({ collapsed: false });
|
||||
}
|
||||
return { getCollapsedWidth, onCollapseChange, onBreakpointChange, onSiderClick };
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle related operations of menu folding
|
||||
*/
|
||||
export function useTrigger() {
|
||||
const { getTrigger } = useMenuSetting();
|
||||
|
||||
const showTrigger = computed(() => {
|
||||
const trigger = unref(getTrigger);
|
||||
return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER;
|
||||
});
|
||||
|
||||
const getTriggerAttr = computed(() => {
|
||||
if (unref(showTrigger)) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
trigger: null,
|
||||
};
|
||||
});
|
||||
|
||||
const getTriggerSlot = computed(() => {
|
||||
if (unref(showTrigger)) {
|
||||
return {
|
||||
trigger: () => <LayoutTrigger />,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
return { getTriggerAttr, getTriggerSlot };
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle menu drag and drop related operations
|
||||
* @param siderRef
|
||||
* @param dragBarRef
|
||||
*/
|
||||
export function useDragLine(siderRef: Ref<any>, dragBarRef: Ref<any>) {
|
||||
const { getMiniWidthNumber, getCollapsed, setMenuSetting, getHasDrag } = useMenuSetting();
|
||||
|
||||
const getDragBarStyle = computed(() => {
|
||||
if (unref(getCollapsed)) {
|
||||
return { left: `${unref(getMiniWidthNumber)}px` };
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
const [exec] = useDebounce(changeWrapWidth, 20);
|
||||
exec();
|
||||
});
|
||||
});
|
||||
|
||||
function renderDragLine() {
|
||||
return (
|
||||
<div
|
||||
class={[`layout-sidebar__darg-bar`, !unref(getHasDrag) ? 'hide' : '']}
|
||||
style={unref(getDragBarStyle)}
|
||||
ref={dragBarRef}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function handleMouseMove(ele: HTMLElement, wrap: HTMLElement, clientX: number) {
|
||||
document.onmousemove = function (innerE) {
|
||||
let iT = (ele as any).left + (innerE.clientX - clientX);
|
||||
innerE = innerE || window.event;
|
||||
const maxT = 600;
|
||||
const minT = unref(getMiniWidthNumber);
|
||||
iT < 0 && (iT = 0);
|
||||
iT > maxT && (iT = maxT);
|
||||
iT < minT && (iT = minT);
|
||||
ele.style.left = wrap.style.width = iT + 'px';
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
// Drag and drop in the menu area-release the mouse
|
||||
function removeMouseup(ele: any) {
|
||||
const wrap = unref(siderRef).$el;
|
||||
document.onmouseup = function () {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
const width = parseInt(wrap.style.width);
|
||||
const miniWidth = unref(getMiniWidthNumber);
|
||||
|
||||
if (!unref(getCollapsed)) {
|
||||
width > miniWidth + 20
|
||||
? setMenuSetting({ menuWidth: width })
|
||||
: setMenuSetting({ collapsed: true });
|
||||
} else {
|
||||
width > miniWidth && setMenuSetting({ collapsed: false, menuWidth: width });
|
||||
}
|
||||
ele.releaseCapture?.();
|
||||
};
|
||||
}
|
||||
|
||||
function changeWrapWidth() {
|
||||
const ele = unref(dragBarRef) as any;
|
||||
const side = unref(siderRef);
|
||||
|
||||
const wrap = (side || {}).$el;
|
||||
ele &&
|
||||
(ele.onmousedown = (e: any) => {
|
||||
wrap.style.transition = 'unset';
|
||||
const clientX = e?.clientX;
|
||||
ele.left = ele.offsetLeft;
|
||||
handleMouseMove(ele, wrap, clientX);
|
||||
removeMouseup(ele);
|
||||
ele.setCapture?.();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return { renderDragLine };
|
||||
}
|
Reference in New Issue
Block a user