🐛(component): splitPanel

space 修改为像素,其他自适应

ISSUES CLOSED: https://gitee.com/layui/layui-vue/issues/I5FB3S
This commit is contained in:
dingyongya 2022-07-11 18:09:21 +08:00
parent afec6ca6cd
commit 4a877f81f5
12 changed files with 141 additions and 101 deletions

View File

@ -4,7 +4,6 @@
position: relative;
.lay-split-panel-item {
height: 100%;
flex-grow: 1;
border: 1px #eeeeee solid;
}
.lay-split-panel-item-move {

View File

@ -1,14 +1,15 @@
<script lang="ts">
export default {
name: "laySplitPanel",
name: "LaySplitPanel",
};
</script>
<script setup lang="ts">
import { ref, watch, provide, withDefaults, onMounted } from "vue";
import "./index.less";
import { useMousePressed } from "@vueuse/core";
export interface LayStepProps {
interface LayStepProps {
vertical?: boolean;
minSize?: number;
}
@ -17,21 +18,20 @@ const props = withDefaults(defineProps<LayStepProps>(), {
vertical: false,
minSize: 50,
});
const target = ref();
const { pressed } = useMousePressed({ target: target });
let domEvent = ref();
let domStatus = ref(false);
const target = ref();
let domStatus = ref(pressed);
let parentVertical = ref();
onMounted(() => {
const boxWidth = target.value.offsetWidth;
const boxHeight = target.value.offsetHeight;
window.addEventListener("scroll", (event) => {
console.log(event);
});
target.value.addEventListener(
"mousemove",
(event: { layerX: any; layerY: any }) => {
if (domStatus.value) {
if (domStatus.value && domEvent.value) {
const prevDom = domEvent.value.target.previousElementSibling;
const nextDom = domEvent.value.target.nextElementSibling;
if (!props.vertical) {
@ -50,11 +50,11 @@ onMounted(() => {
) {
return false;
}
prevDom.style.width =
prevDom.style.flexBasis =
((event.layerX - prevDomLeft) / (prevDomWidth + nextDomWidth + 5)) *
otherWidthPercentage +
"%";
nextDom.style.width =
nextDom.style.flexBasis =
((boxWidth - (event.layerX - prevDomLeft) - otherWidth) /
(prevDomWidth + nextDomWidth + 5)) *
otherWidthPercentage +
@ -76,12 +76,12 @@ onMounted(() => {
) {
return false;
}
prevDom.style.height =
prevDom.style.flexBasis =
((event.layerY - prevDomTop) /
(prevDomHeight + nextDomHeight + 5)) *
otherHeightPercentage +
"%";
nextDom.style.height =
nextDom.style.flexBasis =
((boxHeight - (event.layerY - prevDomTop) - otherHeight) /
(prevDomHeight + nextDomHeight + 5)) *
otherHeightPercentage +
@ -92,13 +92,16 @@ onMounted(() => {
);
});
const moveChange = (event: any, status: boolean) => {
const moveChange = (event: any, status: boolean, isVertical: boolean) => {
domEvent.value = event;
domStatus.value = status;
parentVertical.value = isVertical;
};
const mouseup = () => {
domStatus.value = false;
domEvent.value = null;
parentVertical.value = false;
};
//
@ -116,6 +119,7 @@ watch(steps, () => {
provide("laySplitPanel", {
props,
steps,
target,
moveChange,
});
</script>

View File

@ -14,12 +14,11 @@ import {
onBeforeUnmount,
reactive,
withDefaults,
watch,
} from "vue";
import type { ComputedRef } from "vue";
export interface LayStepItemProps {
interface LayStepItemProps {
space?: number;
}
@ -34,11 +33,6 @@ const setIndex = (val: number) => {
index.value = val;
};
const mousedown = (event: any) => {
moveStatus.value = true;
parents.moveChange(event, true);
};
const mouseup = (event: any) => {
moveStatus.value = false;
};
@ -47,6 +41,34 @@ const stepsCount = computed(() => {
return parents.steps.value.length;
});
const initSpace = (parentSpace: any, key: string) => {
const childList = Array.from(parentElement.value.children);
childList.forEach((item: any, index: number) => {
if (index === 0 || index % 2 === 0) {
item.style.flexBasis = (item[key] / parentSpace) * 100 + "%";
item.style.flexGrow = 0;
}
});
};
const mousedown = (event: any) => {
let parentSpace = 0;
if (!isVertical.value) {
parentSpace = parentElement.value.offsetWidth;
initSpace(parentSpace, "offsetWidth");
} else {
parentSpace = parentElement.value.offsetHeight;
initSpace(parentSpace, "offsetHeight");
}
moveStatus.value = true;
parents.moveChange(event, true, isVertical.value);
};
const parentElement = computed(() => {
return parents.target.value;
});
const isVertical = computed(() => {
return parents.props.vertical;
});
@ -63,9 +85,8 @@ const isStart: ComputedRef<boolean> = computed(() => {
const stepItemState = reactive({
itemId: computed(() => currentInstance?.uid),
setIndex,
width: [],
space: props.space,
});
parents.steps.value = [...parents.steps.value, stepItemState];
onMounted(() => {});
@ -85,16 +106,17 @@ onBeforeUnmount(() => {
v-on="{ mousedown: mousedown, mouseup: mouseup }"
></div>
<div
ref="laySplitPanelItem"
v-if="isVertical"
:class="['lay-split-panel-item']"
:style="{ height: `${space ? space : (100 + space) / stepsCount}%` }"
:style="{ flexBasis: `${space}px`, flexGrow: space ? 0 : 1 }"
>
<slot></slot>
</div>
<div
v-else
:class="['lay-split-panel-item']"
:style="{ width: `${space ? space : (100 + space) / stepsCount}%` }"
:style="{ flexBasis: `${space}px`, flexGrow: space ? 0 : 1 }"
>
<slot></slot>
</div>

View File

@ -128,7 +128,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
if (column.fixed == "left") {
var left = 0;
for (var i = 0; i < columnIndex; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "left") {
if (props.columns[i].fixed && props.columns[i].fixed == "left") {
left = left + props.columns[i]?.width.replace("px", "");
}
}
@ -136,7 +136,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
} else {
var right = 0;
for (var i = columnIndex + 1; i < props.columns.length; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "right") {
if (props.columns[i].fixed && props.columns[i].fixed == "right") {
right = right + props.columns[i]?.width.replace("px", "");
}
}
@ -150,7 +150,7 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
if (column.fixed == "left") {
var left = true;
for (var i = columnIndex + 1; i < props.columns.length; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "left") {
if (props.columns[i].fixed && props.columns[i].fixed == "left") {
left = false;
}
}
@ -158,14 +158,14 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
} else {
var right = true;
for (var i = 0; i < columnIndex; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "right") {
if (props.columns[i].fixed && props.columns[i].fixed == "right") {
right = false;
}
}
return `layui-table-fixed-right-first`;
}
}
}
};
</script>
<template>
@ -258,7 +258,7 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
renderCellStyle(data, column, index, columnIndex),
]"
:class="[
renderFixedClassName(column, columnIndex),
renderFixedClassName(column, columnIndex),
renderCellClassName(data, column, index, columnIndex),
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
]"

View File

@ -255,7 +255,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
if (column.fixed == "left") {
var left = 0;
for (var i = 0; i < columnIndex; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "left") {
if (props.columns[i].fixed && props.columns[i].fixed == "left") {
left = left + props.columns[i]?.width.replace("px", "");
}
}
@ -263,7 +263,7 @@ const renderFixedStyle = (column: any, columnIndex: number) => {
} else {
var right = 0;
for (var i = columnIndex + 1; i < props.columns.length; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "right") {
if (props.columns[i].fixed && props.columns[i].fixed == "right") {
right = right + props.columns[i]?.width.replace("px", "");
}
}
@ -277,22 +277,22 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
if (column.fixed == "left") {
var left = true;
for (var i = columnIndex + 1; i < props.columns.length; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "left") {
if (props.columns[i].fixed && props.columns[i].fixed == "left") {
left = false;
}
}
return left ? `layui-table-fixed-left-last` : '';
return left ? `layui-table-fixed-left-last` : "";
} else {
var right = true;
for (var i = 0; i < columnIndex; i++) {
if(props.columns[i].fixed && props.columns[i].fixed == "right") {
if (props.columns[i].fixed && props.columns[i].fixed == "right") {
right = false;
}
}
return right ? `layui-table-fixed-right-first` : '';
return right ? `layui-table-fixed-right-first` : "";
}
}
}
};
</script>
<template>
@ -379,7 +379,7 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
class="layui-table-cell"
:class="[
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
renderFixedClassName(column, columnIndex)
renderFixedClassName(column, columnIndex),
]"
:style="[
{

View File

@ -1,6 +1,8 @@
<template>
<template v-if="enable">
<LayCollapseTransition v-if="type === 'collapse'"><slot></slot></LayCollapseTransition>
<LayCollapseTransition v-if="type === 'collapse'"
><slot></slot
></LayCollapseTransition>
<LayFadeTransition v-if="type === 'fade'"><slot></slot></LayFadeTransition>
</template>
<template v-else>
@ -22,14 +24,14 @@ import LayFadeTransition from "./transitions/fadeTransition.vue";
export interface LayTransitionProps {
type?: string;
enable?: boolean;
time?:string|number;
time?: string | number;
}
const props = withDefaults(defineProps<LayTransitionProps>(), {
type: "collapse",
enable: true,
time:0.3
time: 0.3,
});
provide('time',props.time)
provide("time", props.time);
</script>

View File

@ -18,9 +18,9 @@ export default {
</script>
<script setup lang="ts">
import { inject } from 'vue';
import { inject } from "vue";
const time=inject('time')
const time = inject("time");
const elTransition = `${time}s height ease-in-out, ${time}s padding-top ease-in-out, ${time}s padding-bottom ease-in-out`;
const beforeEnter = (el: any) => {

View File

@ -4,10 +4,10 @@
</transition>
</template>
<script setup lang="ts">
import { inject,ref } from 'vue';
import { inject, ref } from "vue";
const time=inject('time')
const transition=ref(`opacity ${time}s ease`);
const time = inject("time");
const transition = ref(`opacity ${time}s ease`);
</script>
<style>
.fade-enter-from,

View File

@ -65,9 +65,7 @@ const nodeIconType = (node: TreeData): string => {
return "";
}
if (node.children.length !== 0) {
return !node.isLeaf
? "layui-icon-addition"
: "layui-icon-subtraction";
return !node.isLeaf ? "layui-icon-addition" : "layui-icon-subtraction";
}
return "layui-icon-file";
};
@ -90,39 +88,40 @@ function handleTitleClick(node: TreeData) {
}
emit("node-click", node);
}
function handleRowClick(node:TreeData){
if(!props.showLine){
function handleRowClick(node: TreeData) {
if (!props.showLine) {
handleTitleClick(node);
}
}
//
const isChildAllSelected=computed(()=>{
function _isChildAllSelected(node:TreeData):boolean{
if(!props.showCheckbox){
const isChildAllSelected = computed(() => {
function _isChildAllSelected(node: TreeData): boolean {
if (!props.showCheckbox) {
return false;
}
let childSelectNum=0;
let res=false;// true false
let childSelectNum = 0;
let res = false; // true false
for (const item of node.children) {
if(item.isChecked) childSelectNum++;
if (item.isChecked) childSelectNum++;
}
if(childSelectNum>0) node.isChecked=true;// checkedKeys
if(childSelectNum==node.children.length){//
if (childSelectNum > 0) node.isChecked = true; // checkedKeys
if (childSelectNum == node.children.length) {
//
for (const item of node.children) {
res=_isChildAllSelected(item)
if(res) break;
res = _isChildAllSelected(item);
if (res) break;
}
}else{
res=true;
} else {
res = true;
}
return res;
}
return function(node:TreeData):boolean{
let res=_isChildAllSelected(node)
return function (node: TreeData): boolean {
let res = _isChildAllSelected(node);
return res;
}
})
};
});
</script>
<template>
@ -143,7 +142,10 @@ const isChildAllSelected=computed(()=>{
{ 'layui-tree-iconClick': true },
]"
>
<lay-icon :type="nodeIconType(node)" @click.stop="handleIconClick(node)" />
<lay-icon
:type="nodeIconType(node)"
@click.stop="handleIconClick(node)"
/>
</span>
<lay-checkbox
v-if="showCheckbox"
@ -156,7 +158,7 @@ const isChildAllSelected=computed(()=>{
handleChange(checked, node);
}
"
:isIndeterminate='isChildAllSelected(node)'
:isIndeterminate="isChildAllSelected(node)"
/>
<span
:class="{

View File

@ -6,7 +6,7 @@ export default {
<script lang="ts" setup>
import TreeNode from "./TreeNode.vue";
import { computed, useSlots, watch,ref } from "vue";
import { computed, useSlots, watch, ref } from "vue";
import { useTree } from "./useTree";
import { TreeData } from "./tree";
import { StringFn, StringOrNumber, KeysType, EditType } from "./tree.type";
@ -43,7 +43,9 @@ interface TreeEmits {
}
const props = withDefaults(defineProps<TreeProps>(), {
checkedKeys:()=>{ return [] },
checkedKeys: () => {
return [];
},
showCheckbox: false,
edit: false,
collapseTransition: true,
@ -71,26 +73,26 @@ const className = computed(() => {
};
});
let tree=ref();
let nodeList=ref();
const loadNodeList=()=>{
let { tree:_tree, nodeList:_nodeList }=useTree(props, emit);
tree.value=_tree
nodeList.value=_nodeList.value
}
let tree = ref();
let nodeList = ref();
const loadNodeList = () => {
let { tree: _tree, nodeList: _nodeList } = useTree(props, emit);
tree.value = _tree;
nodeList.value = _nodeList.value;
};
watch(
() => props.data,
() => {
loadNodeList();
},
{ deep: true,immediate:true}
)
{ deep: true, immediate: true }
);
watch(
() => props.checkedKeys,
() => {
loadNodeList()
},
)
loadNodeList();
}
);
function handleClick(node: TreeData) {
const originNode = tree.value.getOriginData(node.id);

View File

@ -106,7 +106,7 @@ class Tree {
children: nodeChildren ? nodeChildren : [],
parentKey: parentKey,
isRoot: parentKey === "",
isDisabled:false,
isDisabled: false,
isChecked: false,
isLeaf: false,
hasNextSibling: hasNextSibling,
@ -114,14 +114,12 @@ class Tree {
});
node.isDisabled = nodeDisabled;
if(parentNode && parentNode.isChecked){
node.isChecked=true;
}else{
node.isChecked=checkedKeys.includes(nodeKey);
if (parentNode && parentNode.isChecked) {
node.isChecked = true;
} else {
node.isChecked = checkedKeys.includes(nodeKey);
}
node.isLeaf = parentNode
? parentNode.isLeaf
: expandKeys.includes(nodeKey);
node.isLeaf = parentNode ? parentNode.isLeaf : expandKeys.includes(nodeKey);
node.isLeaf = nodeIsLeaf;
if (!nodeMap.has(nodeKey)) {

View File

@ -25,6 +25,16 @@
<script>
</script>
<style>
.lay-split-panel-item{
display: flex;
font-size: 16px;
font-weight: bold;
justify-content: center;
align-items: center;
}
</style>
:::
::: title 自定义比例
@ -36,9 +46,9 @@
<template>
<div>
<lay-split-panel style="height: 300px">
<lay-split-panel-item :space="30">1</lay-split-panel-item>
<lay-split-panel-item :space="20">2</lay-split-panel-item>
<lay-split-panel-item :space="50">3</lay-split-panel-item>
<lay-split-panel-item :space="200">1</lay-split-panel-item>
<lay-split-panel-item>2</lay-split-panel-item>
<lay-split-panel-item :space="200">3</lay-split-panel-item>
</lay-split-panel>
</div>
</template>
@ -78,13 +88,14 @@
<template>
<div>
<lay-split-panel style="height: 600px;">
<lay-split-panel-item :space="60">
<lay-split-panel-item :space="300">
<lay-split-panel :vertical="true" style="height: 600px; width: 100%">
<lay-split-panel-item :space="40">1</lay-split-panel-item>
<lay-split-panel-item :space="40">2</lay-split-panel-item>
<lay-split-panel-item :space="200">1</lay-split-panel-item>
<lay-split-panel-item>2</lay-split-panel-item>
</lay-split-panel>
</lay-split-panel-item>
<lay-split-panel-item :space="40">2</lay-split-panel-item>
<lay-split-panel-item>2</lay-split-panel-item>
<lay-split-panel-item>2</lay-split-panel-item>
</lay-split-panel>
</div>
</template>
@ -112,7 +123,7 @@
| 属性 | 描述 | 类型 |可选值 | 默认值|
| ----- | ---- | ------ | ---| ---|
| space | 默认每个站多大比例(`%`, 设置一个,<br/> 其他的都需要设置,合计为(`100` | number | - | 按照个数平分 |
| space | 默认每个`px` , 其他的自动平分 | number | - | 按照个数平分 |
:::
::: contributor splitPanel