|
|
|
|
@ -3,9 +3,7 @@
|
|
|
|
|
style="width: fit-content; display: flex; flex-direction: column; position: relative;"
|
|
|
|
|
v-if="store.nowComponentsData !== null && (componentVisible || store.designerMode)"
|
|
|
|
|
:id="componentId"
|
|
|
|
|
:class="[
|
|
|
|
|
'dynamic-component',
|
|
|
|
|
{ 'hover-state': isHovered && store.designerMode },
|
|
|
|
|
:class="['dynamic-component',{ 'hover-state': isHovered && store.designerMode },
|
|
|
|
|
{ 'click-state': componentSelected && store.designerMode &&isComponent }
|
|
|
|
|
]"
|
|
|
|
|
@click.stop="handleClick"
|
|
|
|
|
@ -17,13 +15,26 @@
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="componentSelected && store.designerMode&&isComponent" class="component-header" :style="headerStyle">
|
|
|
|
|
<div style="background-color:#3457cc;color: #ffffff;padding: 5px ;margin-right: 2px">{{ componentName }}</div>
|
|
|
|
|
<div style="background-color:#3457cc;color:#ffffff;padding: 6px 5px 5px 5px;display: flex;width: fit-content;flex-wrap: nowrap">
|
|
|
|
|
<div
|
|
|
|
|
style="background-color:#3457cc;color:#ffffff;padding: 6px 5px 5px 5px;display: flex;width: fit-content;flex-wrap: nowrap">
|
|
|
|
|
<icon-copy class="clickable" size="20"/>
|
|
|
|
|
<icon-edit class="clickable" @click="handleEditFunc" size="20"/>
|
|
|
|
|
<icon-delete class="clickable" @click="handleDeleteFunc" size="20"/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="component-content">
|
|
|
|
|
<VueDraggable
|
|
|
|
|
v-model="componentChildren"
|
|
|
|
|
:animation="150"
|
|
|
|
|
group="designer"
|
|
|
|
|
ghost-class="ghost"
|
|
|
|
|
chosen-class="chosen"
|
|
|
|
|
class="canvas"
|
|
|
|
|
@start="onComponentStart"
|
|
|
|
|
@update="onComponentUpdate"
|
|
|
|
|
@stop="onComponentEnd"
|
|
|
|
|
@add="onComponentAdd"
|
|
|
|
|
>
|
|
|
|
|
<component
|
|
|
|
|
:is="componentType"
|
|
|
|
|
v-bind="componentPropsWithDisabled"
|
|
|
|
|
@ -34,18 +45,21 @@
|
|
|
|
|
<template v-for="child in componentChildren" :key="child.id">
|
|
|
|
|
<DynamicComponent :componentData="child"/>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-for="(slot, key, index) in componentSlots" :key="index" v-slot:[key]>
|
|
|
|
|
<template v-for="(slot, key, index) in componentSlots" :key="key" v-slot:[key]>
|
|
|
|
|
<DynamicComponent :component-data="slot"/>
|
|
|
|
|
</template>
|
|
|
|
|
</component>
|
|
|
|
|
</VueDraggable>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { defineProps, ref, computed, onMounted, watch, markRaw, nextTick } from 'vue';
|
|
|
|
|
import {ref, computed, onMounted, watch, markRaw, nextTick} from 'vue';
|
|
|
|
|
import {componentMapping} from './componentMapping';
|
|
|
|
|
import {useSchemeStore} from '../stores/useSchemeStore';
|
|
|
|
|
import {DraggableEvent, VueDraggable} from "vue-draggable-plus";
|
|
|
|
|
|
|
|
|
|
const store = useSchemeStore();
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
@ -56,22 +70,45 @@ const componentId = computed(() => props.componentData?.id || '');
|
|
|
|
|
const componentName = computed(() => props.componentData?.name || 'Unnamed Component');
|
|
|
|
|
const componentType = computed(() => markRaw(componentMapping[props.componentData?.type]) || 'div');
|
|
|
|
|
const componentProps = computed(() => props.componentData?.props || {});
|
|
|
|
|
const componentDisable = computed(() => props.componentData?.disable || false);
|
|
|
|
|
const componentDisable = computed(() => props.componentData?.disable);
|
|
|
|
|
const componentVisible = computed(() => props.componentData?.visible);
|
|
|
|
|
const componentChildren = computed(() => props.componentData?.children || []);
|
|
|
|
|
const componentChildren = ref(props.componentData?.children);
|
|
|
|
|
const componentText = computed(() => props.componentData?.text || '');
|
|
|
|
|
const componentClass = computed(() => props.componentData?.class || []);
|
|
|
|
|
const componentStyle = computed(() => props.componentData?.style || []);
|
|
|
|
|
const componentSlots = computed(() => props.componentData?.slots || {});
|
|
|
|
|
const componentSelected = computed(() => store.nowComponentsData?.id && props.componentData?.id === store.nowComponentsData?.id);
|
|
|
|
|
|
|
|
|
|
// 设计器控制参数
|
|
|
|
|
const componentMove = computed(() => props.componentData?.designer?.move | false);
|
|
|
|
|
const componentMoveSibling = computed(() => props.componentData?.designer?.moveSibling | false);
|
|
|
|
|
const componentSelect = computed(() => props.componentData?.designer?.select | false);
|
|
|
|
|
const componentDel= computed(() => props.componentData?.designer?.del | false);
|
|
|
|
|
const componentDynamic= computed(() => props.componentData?.designer?.dynamic | false);
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
debugger
|
|
|
|
|
isComponent.value = props.componentData?.type != 'AdaptivePage';
|
|
|
|
|
adjustHeaderPosition();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onComponentStart = (event: DraggableEvent) => {
|
|
|
|
|
console.log("onComponentStart", event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onComponentEnd = (event: DraggableEvent) => {
|
|
|
|
|
console.log("onComponentEnd", event);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
const onComponentAdd = (event: DraggableEvent) => {
|
|
|
|
|
console.log("onComponentAdd", event);
|
|
|
|
|
let obj = getCurrentSchemeObj()
|
|
|
|
|
obj.children = componentChildren.value
|
|
|
|
|
store.updateScheme(obj.id, obj)
|
|
|
|
|
}
|
|
|
|
|
const onComponentUpdate = (event: DraggableEvent) => {
|
|
|
|
|
console.log("onComponentUpdate", event);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// 确保 componentProps 包含 disabled 属性
|
|
|
|
|
const componentPropsWithDisabled = computed(() => ({
|
|
|
|
|
...componentProps.value,
|
|
|
|
|
@ -151,7 +188,6 @@ const adjustHeaderPosition = () => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(() => componentSelected.value, () => {
|
|
|
|
|
if (componentSelected.value) {
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
@ -162,7 +198,7 @@ watch(() => componentSelected.value, () => {
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
<style>
|
|
|
|
|
.dynamic-component {
|
|
|
|
|
position: relative;
|
|
|
|
|
width: fit-content;
|
|
|
|
|
@ -213,4 +249,18 @@ watch(() => componentSelected.value, () => {
|
|
|
|
|
.clickable {
|
|
|
|
|
cursor: pointer; /* 当鼠标悬停在此元素上时,鼠标指针变为手形 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.canvas {
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
.ghost {
|
|
|
|
|
background-color: #f2f3f5 !important;
|
|
|
|
|
}
|
|
|
|
|
.chosen {
|
|
|
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
z-index: 1001;
|
|
|
|
|
}
|
|
|
|
|
</style>
|