1.分割面板
This commit is contained in:
parent
3c03862043
commit
47c8714896
40
example/docs/zh-CN/components/splitPanel.md
Normal file
40
example/docs/zh-CN/components/splitPanel.md
Normal 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>
|
||||||
|
|
||||||
|
:::
|
@ -76,6 +76,12 @@ const zhCN = [
|
|||||||
component: Component,
|
component: Component,
|
||||||
meta: { title: "组件" },
|
meta: { title: "组件" },
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: "/zh-CN/components/splitPanel",
|
||||||
|
component: () =>
|
||||||
|
import("../../docs/zh-CN/components/splitPanel.md"),
|
||||||
|
meta: { title: "分割面板" },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/zh-CN/components/skeleton",
|
path: "/zh-CN/components/skeleton",
|
||||||
component: () => import("../../docs/zh-CN/components/skeleton.md"),
|
component: () => import("../../docs/zh-CN/components/skeleton.md"),
|
||||||
|
12
src/index.ts
12
src/index.ts
@ -70,9 +70,13 @@ import LaySkeleton from "./module/skeleton/index";
|
|||||||
import LaySkeletonItem from "./module/skeletonItem/index";
|
import LaySkeletonItem from "./module/skeletonItem/index";
|
||||||
import LayStep from "./module/step/index";
|
import LayStep from "./module/step/index";
|
||||||
import LayStepItem from "./module/stepItem/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> = {
|
const components: Record<string, IDefineComponent> = {
|
||||||
|
LaySplitPanel,
|
||||||
|
LaySplitPanelItem,
|
||||||
LayRadio,
|
LayRadio,
|
||||||
LayButton,
|
LayButton,
|
||||||
LayIcon,
|
LayIcon,
|
||||||
@ -137,7 +141,7 @@ const components: Record<string, IDefineComponent> = {
|
|||||||
LayCountUp,
|
LayCountUp,
|
||||||
LayStep,
|
LayStep,
|
||||||
LayStepItem,
|
LayStepItem,
|
||||||
LaySubMenu
|
LaySubMenu,
|
||||||
};
|
};
|
||||||
|
|
||||||
const install = (app: App, options?: InstallOptions): void => {
|
const install = (app: App, options?: InstallOptions): void => {
|
||||||
@ -150,6 +154,8 @@ const install = (app: App, options?: InstallOptions): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
LaySplitPanel,
|
||||||
|
LaySplitPanelItem,
|
||||||
LayRadio,
|
LayRadio,
|
||||||
LayButton,
|
LayButton,
|
||||||
LayIcon,
|
LayIcon,
|
||||||
@ -214,7 +220,7 @@ export {
|
|||||||
LayCountUp,
|
LayCountUp,
|
||||||
LayStep,
|
LayStep,
|
||||||
LayStepItem,
|
LayStepItem,
|
||||||
LaySubMenu
|
LaySubMenu,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { layer };
|
export { layer };
|
||||||
|
34
src/module/splitPanel/index.less
Normal file
34
src/module/splitPanel/index.less
Normal 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;
|
||||||
|
//}
|
||||||
|
}
|
9
src/module/splitPanel/index.ts
Normal file
9
src/module/splitPanel/index.ts
Normal 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;
|
96
src/module/splitPanel/index.vue
Normal file
96
src/module/splitPanel/index.vue
Normal 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>
|
9
src/module/splitPanelItem/index.ts
Normal file
9
src/module/splitPanelItem/index.ts
Normal 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;
|
98
src/module/splitPanelItem/index.vue
Normal file
98
src/module/splitPanelItem/index.vue
Normal 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>
|
Loading…
Reference in New Issue
Block a user