This commit is contained in:
lhj
2024-11-14 00:46:35 +08:00
parent 116e28b8fa
commit 402e686d87

View File

@ -1,6 +1,6 @@
<template>
<div
style="width: fit-content; display: flex; flex-direction: column;"
style="width: fit-content; display: flex; flex-direction: column; position: relative;"
v-if="componentVisible || store.designerMode"
:id="componentId"
:class="[
@ -12,7 +12,7 @@
@mouseover="isHovered = true"
@mouseleave="isHovered = false"
>
<div v-if="isClicked" class="component-header">
<div v-if="isClicked" class="component-header" :style="headerStyle">
<span>{{ componentName }}</span>
<button style="color: #1057CC" @click="handleFunction('edit')">编辑</button>
<button style="color: #1057CC" @click="handleFunction('delete')">删除</button>
@ -26,7 +26,7 @@
>
{{ componentText }}
<template v-for="child in componentChildren" :key="child.id">
<DynamicComponent :component-data="child" />
<DynamicComponent :componentData="child" />
</template>
<template v-for="(slot, key, index) in componentSlots" :key="index" v-slot:[key]>
<DynamicComponent :component-data="slot" />
@ -37,7 +37,7 @@
</template>
<script setup lang="ts">
import { defineProps, ref, computed, onMounted, watch, markRaw } from 'vue';
import { defineProps, ref, computed, onMounted, watch, markRaw, nextTick } from 'vue';
import { componentMapping } from './componentMapping';
import { useSchemeStore } from '../stores/useSchemeStore';
@ -46,10 +46,6 @@ const props = defineProps({
componentData: Object
});
onMounted(() => {
console.log(props.componentData);
});
const componentId = computed(() => props.componentData?.id || '');
const componentName = computed(() => props.componentData?.name || 'Unnamed Component');
const componentType = computed(() => markRaw(componentMapping[props.componentData?.type]) || 'div');
@ -88,6 +84,69 @@ const handleFunction = (action: string) => {
console.log(`Action: ${action}`);
// 处理编辑或删除操作
};
const headerStyle = ref({});
const targetContent = ref<HTMLElement | null>(null);
const adjustHeaderPosition = () => {
const componentEl = document.getElementById(componentId.value);
if (!componentEl) return;
const headerEl = componentEl.querySelector('.component-header');
if (!headerEl) return;
const componentRect = componentEl.getBoundingClientRect();
const headerRect = headerEl.getBoundingClientRect();
let top = 0;
let left = 0;
// 获取最外层组件渲染区域的边界
const containerEl = targetContent.value;
if (!containerEl) return;
const containerRect = containerEl.getBoundingClientRect();
// 计算上下左右的可用空间
const topSpace = componentRect.top - containerRect.top;
const bottomSpace = containerRect.bottom - componentRect.bottom;
const leftSpace = componentRect.left - containerRect.left;
const rightSpace = containerRect.right - componentRect.right;
// 检查上方是否有足够的空间
if (topSpace >= headerRect.height) {
top = -headerRect.height - 10;
left = rightSpace >= headerRect.width ? componentRect.width - headerRect.width : 0;
} else if (bottomSpace >= headerRect.height) {
top = componentRect.height + 10;
left = rightSpace >= headerRect.width ? componentRect.width - headerRect.width : 0;
} else if (leftSpace >= headerRect.width) {
left = -headerRect.width - 10;
top = 0;
} else if (rightSpace >= headerRect.width) {
left = componentRect.width + 10;
top = 0;
}
headerStyle.value = {
top: `${top}px`,
left: `${left}px`
};
};
onMounted(() => {
console.log(props.componentData);
adjustHeaderPosition();
});
watch(() => isClicked.value, () => {
if (isClicked.value) {
nextTick(() => {
adjustHeaderPosition();
});
}
});
</script>
<style scoped>
@ -108,8 +167,6 @@ const handleFunction = (action: string) => {
.component-header {
position: absolute;
top: -100px; /* 设置为负值,使工具栏浮在主内容之上 */
left: 0;
color: #1057CC;
padding: 5px;
display: flex;
@ -117,6 +174,8 @@ const handleFunction = (action: string) => {
justify-content: space-between;
width: 100%;
z-index: 1000;
background-color: transparent; /* 确保没有背景颜色 */
box-sizing: border-box; /* 确保内边距不会影响宽度 */
}
.component-header span {