Files
vue-vben-admin/src/layouts/default/LayoutSideBar.tsx
2020-11-10 22:45:39 +08:00

213 lines
6.1 KiB
TypeScript

import { computed, defineComponent, nextTick, onMounted, ref, unref } from 'vue';
import { Layout } from 'ant-design-vue';
import LayoutTrigger from './LayoutTrigger';
import { menuStore } from '/@/store/modules/menu';
import { appStore } from '/@/store/modules/app';
import { MenuModeEnum, MenuSplitTyeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
import { useDebounce } from '/@/hooks/core/useDebounce';
import LayoutMenu from './LayoutMenu';
export default defineComponent({
name: 'DefaultLayoutSideBar',
setup() {
const initRef = ref(false);
const brokenRef = ref(false);
const collapseRef = ref(true);
const dragBarRef = ref<Nullable<HTMLDivElement>>(null);
const sideRef = ref<any>(null);
const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig;
});
const getMiniWidth = computed(() => {
const {
menuSetting: { collapsedShowTitle },
} = unref(getProjectConfigRef);
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
});
function onCollapseChange(val: boolean) {
if (initRef.value) {
collapseRef.value = val;
menuStore.commitCollapsedState(val);
} else {
const collapsed = appStore.getProjectConfig.menuSetting.collapsed;
!collapsed && menuStore.commitCollapsedState(val);
}
initRef.value = true;
}
// Menu area drag and drop-mouse movement
function handleMouseMove(ele: any, wrap: any, clientX: number) {
document.onmousemove = function (innerE) {
let iT = ele.left + ((innerE || event).clientX - clientX);
innerE = innerE || window.event;
// let tarnameb = innerE.target || innerE.srcElement;
const maxT = 600;
const minT = unref(getMiniWidth);
iT < 0 && (iT = 0);
iT > maxT && (iT = maxT);
iT < minT && (iT = minT);
ele.style.left = wrap.style.width = iT + 'px';
return false;
};
}
// 菜单区域拖拽 - 鼠标松开
function removeMouseup(ele: any) {
const wrap = unref(sideRef).$el;
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
const width = parseInt(wrap.style.width);
menuStore.commitDragStartState(false);
if (!menuStore.getCollapsedState) {
if (width > unref(getMiniWidth) + 20) {
setMenuWidth(width);
} else {
menuStore.commitCollapsedState(true);
}
} else {
if (width > unref(getMiniWidth)) {
setMenuWidth(width);
menuStore.commitCollapsedState(false);
}
}
ele.releaseCapture && ele.releaseCapture();
};
}
function setMenuWidth(width: number) {
appStore.commitProjectConfigState({
menuSetting: {
menuWidth: width,
},
});
}
function changeWrapWidth() {
const ele = unref(dragBarRef) as any;
const side = unref(sideRef);
const wrap = (side || {}).$el;
ele &&
(ele.onmousedown = (e: any) => {
menuStore.commitDragStartState(true);
wrap.style.transition = 'unset';
const clientX = (e || event).clientX;
ele.left = ele.offsetLeft;
handleMouseMove(ele, wrap, clientX);
removeMouseup(ele);
ele.setCapture && ele.setCapture();
return false;
});
}
function handleBreakpoint(broken: boolean) {
brokenRef.value = broken;
}
onMounted(() => {
nextTick(() => {
const [exec] = useDebounce(changeWrapWidth, 20);
exec();
});
});
const getDragBarStyle = computed(() => {
if (menuStore.getCollapsedState) {
return { left: `${unref(getMiniWidth)}px` };
}
return {};
});
const getCollapsedWidth = computed(() => {
return unref(brokenRef) ? 0 : unref(getMiniWidth);
});
const showTrigger = computed(() => {
const {
menuSetting: { trigger },
} = unref(getProjectConfigRef);
return trigger !== TriggerEnum.NONE && trigger === TriggerEnum.FOOTER;
});
function handleSiderClick(e: ChangeEvent) {
if (!e || !e.target || e.target.className !== 'basic-menu__content') return;
const { collapsed, show } = appStore.getProjectConfig.menuSetting;
if (!collapsed || !show) return;
appStore.commitProjectConfigState({
menuSetting: {
collapsed: false,
},
});
}
function renderDragLine() {
const { menuSetting: { hasDrag = true } = {} } = unref(getProjectConfigRef);
return (
<div
class={[`layout-sidebar__dargbar`, !hasDrag ? 'hide' : '']}
style={unref(getDragBarStyle)}
ref={dragBarRef}
/>
);
}
return () => {
const {
menuSetting: { theme, split: splitMenu },
} = unref(getProjectConfigRef);
const { getCollapsedState, getMenuWidthState } = menuStore;
const triggerDom = unref(showTrigger)
? {
trigger: () => <LayoutTrigger />,
}
: {};
const triggerAttr = unref(showTrigger)
? {}
: {
trigger: null,
};
return (
<Layout.Sider
onClick={handleSiderClick}
onCollapse={onCollapseChange}
breakpoint="md"
width={getMenuWidthState}
collapsed={getCollapsedState}
collapsible
collapsedWidth={unref(getCollapsedWidth)}
theme={theme}
class="layout-sidebar"
ref={sideRef}
onBreakpoint={handleBreakpoint}
{...triggerAttr}
>
{{
...triggerDom,
default: () => (
<>
<LayoutMenu
theme={theme}
menuMode={splitMenu ? MenuModeEnum.INLINE : null}
splitType={splitMenu ? MenuSplitTyeEnum.LEFT : MenuSplitTyeEnum.NONE}
/>
{renderDragLine()}
</>
),
}}
</Layout.Sider>
);
};
},
});