1.分割面板

This commit is contained in:
dingyongya 2022-01-19 09:38:54 +08:00
parent 3c03862043
commit 47c8714896
8 changed files with 301 additions and 3 deletions

View File

@ -0,0 +1,40 @@
::: anchor
:::
::: title 基础使用
:::
::: demo
<template>
<div>
<lay-split-panel style="height: 300px">
<lay-split-panel-item>1</lay-split-panel-item>
<lay-split-panel-item>2</lay-split-panel-item>
</lay-split-panel>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const loading = ref(true);
const active = ref(-1);
const nexts = () => {
if (active.value++ >=3) active.value = 0
};
const previous = () => {
if (active.value-- ===0) active.value = 0
};
return {
loading,
active
}
}
}
</script>
:::

View File

@ -76,6 +76,12 @@ const zhCN = [
component: Component,
meta: { title: "组件" },
children: [
{
path: "/zh-CN/components/splitPanel",
component: () =>
import("../../docs/zh-CN/components/splitPanel.md"),
meta: { title: "分割面板" },
},
{
path: "/zh-CN/components/skeleton",
component: () => import("../../docs/zh-CN/components/skeleton.md"),

View File

@ -70,9 +70,13 @@ import LaySkeleton from "./module/skeleton/index";
import LaySkeletonItem from "./module/skeletonItem/index";
import LayStep from "./module/step/index";
import LayStepItem from "./module/stepItem/index";
import LaySubMenu from "./module/subMenu/index"
import LaySubMenu from "./module/subMenu/index";
import LaySplitPanel from "./module/splitPanel/index";
import LaySplitPanelItem from "./module/splitPanelItem/index";
const components: Record<string, IDefineComponent> = {
LaySplitPanel,
LaySplitPanelItem,
LayRadio,
LayButton,
LayIcon,
@ -137,7 +141,7 @@ const components: Record<string, IDefineComponent> = {
LayCountUp,
LayStep,
LayStepItem,
LaySubMenu
LaySubMenu,
};
const install = (app: App, options?: InstallOptions): void => {
@ -150,6 +154,8 @@ const install = (app: App, options?: InstallOptions): void => {
};
export {
LaySplitPanel,
LaySplitPanelItem,
LayRadio,
LayButton,
LayIcon,
@ -214,7 +220,7 @@ export {
LayCountUp,
LayStep,
LayStepItem,
LaySubMenu
LaySubMenu,
};
export { layer };

View File

@ -0,0 +1,34 @@
.lay-split-panel{
height: 100%;
display: flex;
.lay-split-panel-item {
height: 100%;
flex-grow: 1;
border: 1px #eeeeee solid;
}
.lay-split-panel-item-move{
user-select: none;
pointer-events: none;
cursor: col-resize;
}
.lay-split-panel-line{
height: 100%;
width: 3px;
border: 1px #eeeeee solid;
background-color: #e8e8e8;
border-left: none;
border-right: none;
cursor: col-resize;
}
//.lay-split-panel-line:before{
// content: '';
// position: relative;
// height: 100%;
// left: -5px;
// top: -1px;
// width: 3px;
// border: 1px #eeeeee solid;
// cursor: col-resize;
//}
}

View File

@ -0,0 +1,9 @@
import type { App } from "vue";
import Component from "./index.vue";
import type { IDefineComponent } from "../type/index";
Component.install = (app: App) => {
app.component(Component.name || "laySplitPanel", Component);
};
export default Component as IDefineComponent;

View File

@ -0,0 +1,96 @@
<template>
<div
ref="target"
class="lay-split-panel"
:style="{ cursor: domStatus ? 'col-resize' : '' }"
v-on="{ mouseup: mouseup }"
>
<slot></slot>
</div>
</template>
<script setup name="laySplitPanel" lang="ts">
import {
ref,
watch,
provide,
defineProps,
withDefaults,
defineEmits,
onMounted,
} from "vue";
import "./index.less";
//
export interface LayStepProps {
active?: number;
}
// props
const props = withDefaults(defineProps<LayStepProps>(), {
active: 0,
});
let domEvent = ref();
let domStatus = ref(false);
let otherDom = ref(0);
const target = ref();
const divSetInterval = (width, event) => {
console.log(width);
const boxLeft = target.value.offsetLeft;
const boxWidth = target.value.offsetWidth;
const prevDom = domEvent.value.target.previousElementSibling;
const nextDom = domEvent.value.target.nextElementSibling;
const timer = setInterval(() => {
const prevDomLeft = domEvent.value.target.previousElementSibling.offsetLeft;
const lineOffsetLeft = domEvent.value.target.offsetLeft;
prevDom.style.width = ((event.layerX - prevDomLeft) / boxWidth) * 100 + "%";
nextDom.style.width =
((boxWidth - boxLeft - event.layerX - 5) / boxWidth) * 100 + "%";
console.log(event.layerX, prevDomLeft);
}, 100);
if (prevDom?.clientWidth === width) {
clearInterval(timer);
}
};
onMounted(() => {
const boxLeft = target.value.offsetLeft;
const boxWidth = target.value.offsetWidth;
const prevDomLeft = domEvent.value.target.previousElementSibling.offsetLeft;
target.value.addEventListener("mousemove", (event: { layerX: any }) => {
if (domStatus.value) {
divSetInterval(event.layerX - prevDomLeft, event);
console.log(event.layerX, prevDomLeft);
}
});
});
const moveChange = (event: any, status: boolean) => {
domEvent.value = event;
domStatus.value = status;
};
const mouseup = () => {
domStatus.value = false;
};
//
const emits = defineEmits(["onChange"]);
//
const steps = ref([]);
// lay-split-panel-item
watch(steps, () => {
steps.value.forEach(
(instance: { setIndex: (arg0: any) => void }, index: any) => {
instance.setIndex(index);
}
);
});
// lay-split-panel-item
provide("laySplitPanel", {
props,
steps,
moveChange,
});
</script>

View File

@ -0,0 +1,9 @@
import type { App } from "vue";
import Component from "./index.vue";
import type { IDefineComponent } from "../type/index";
Component.install = (app: App) => {
app.component(Component.name || "laySplitPanelItem", Component);
};
export default Component as IDefineComponent;

View File

@ -0,0 +1,98 @@
<template>
<div
v-if="!isStart"
:class="[!isStart ? 'lay-split-panel-line' : '']"
:style="{ cursor: 'col-resize' }"
ref="el"
v-on="{ mousedown: mousedown, mouseup: mouseup }"
></div>
<div :class="['lay-split-panel-item']">
<slot> {{ parents.elementX }}{{ pressed }}</slot>
</div>
</template>
<script setup name="laySplitPanelItem" lang="ts">
import {
ref,
inject,
onMounted,
computed,
getCurrentInstance,
onBeforeUnmount,
reactive,
defineProps,
withDefaults,
watch,
} from "vue";
import type { ComputedRef } from "vue";
export interface LayStepItemProps {
title?: string;
content?: string;
icon?: string;
status?: string;
}
const props = withDefaults(defineProps<LayStepItemProps>(), {
title: "",
content: "",
icon: "",
status: "",
});
const index = ref(-1);
const parents: any = inject("laySplitPanel");
const currentInstance: any = getCurrentInstance();
const moveStatus = ref(false);
const setIndex = (val: number) => {
index.value = val;
};
const mousedown = (event: any) => {
moveStatus.value = true;
const prevDomWidth = event.target.previousElementSibling.offsetWidth;
const lineOffsetLeft = event.target.offsetLeft;
parents.moveChange(event, true);
console.log(prevDomWidth);
console.log(lineOffsetLeft);
};
const mouseup = (event: any, index: any) => {
moveStatus.value = false;
};
const stepsCount = computed(() => {
return parents.steps.value.length;
});
const isVertical = computed(() => {
return parents.props.direction === "vertical";
});
const isLast: ComputedRef<boolean> = computed(() => {
return (
parents.steps.value[stepsCount.value - 1]?.itemId === currentInstance.uid
);
});
const isStart: ComputedRef<boolean> = computed(() => {
return parents.steps.value[0]?.itemId === currentInstance.uid;
});
const stepItemState = reactive({
itemId: computed(() => currentInstance?.uid),
setIndex,
});
parents.steps.value = [...parents.steps.value, stepItemState];
onMounted(() => {});
onBeforeUnmount(() => {
parents.steps.value = parents.steps.value.filter(
(instance: { itemId: any }) => instance.itemId !== currentInstance.uid
);
});
</script>