From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/components/DiyEditor/components/ComponentContainer.vue | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 239 insertions(+), 0 deletions(-)
diff --git a/src/components/DiyEditor/components/ComponentContainer.vue b/src/components/DiyEditor/components/ComponentContainer.vue
new file mode 100644
index 0000000..4856722
--- /dev/null
+++ b/src/components/DiyEditor/components/ComponentContainer.vue
@@ -0,0 +1,239 @@
+<template>
+ <div :class="['component', { active: active }]">
+ <div
+ :style="{
+ ...style
+ }"
+ >
+ <component :is="component.id" :property="component.property" />
+ </div>
+ <div class="component-wrap">
+ <!-- 宸︿晶锛氱粍浠跺悕锛堟偓娴殑灏忚创鏉★級 -->
+ <div class="component-name" v-if="component.name">
+ {{ component.name }}
+ </div>
+ <!-- 鍙充晶锛氱粍浠舵搷浣滃伐鍏锋爮 -->
+ <div class="component-toolbar" v-if="showToolbar && component.name && active">
+ <VerticalButtonGroup type="primary">
+ <el-tooltip content="涓婄Щ" placement="right">
+ <el-button :disabled="!canMoveUp" @click.stop="handleMoveComponent(-1)">
+ <Icon icon="ep:arrow-up" />
+ </el-button>
+ </el-tooltip>
+ <el-tooltip content="涓嬬Щ" placement="right">
+ <el-button :disabled="!canMoveDown" @click.stop="handleMoveComponent(1)">
+ <Icon icon="ep:arrow-down" />
+ </el-button>
+ </el-tooltip>
+ <el-tooltip content="澶嶅埗" placement="right">
+ <el-button @click.stop="handleCopyComponent()">
+ <Icon icon="ep:copy-document" />
+ </el-button>
+ </el-tooltip>
+ <el-tooltip content="鍒犻櫎" placement="right">
+ <el-button @click.stop="handleDeleteComponent()">
+ <Icon icon="ep:delete" />
+ </el-button>
+ </el-tooltip>
+ </VerticalButtonGroup>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+// 娉ㄥ唽鎵�鏈夌殑缁勪欢
+import { components } from '../components/mobile/index'
+export default {
+ components: { ...components }
+}
+</script>
+<script setup lang="ts">
+import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
+import { propTypes } from '@/utils/propTypes'
+import { object } from 'vue-types'
+
+/**
+ * 缁勪欢瀹瑰櫒锛氱洰鍓嶅湪涓棿閮ㄥ垎
+ * 鐢ㄤ簬鍖呰9缁勪欢锛屼负缁勪欢鎻愪緵 鑳屾櫙銆佸杈硅窛銆佸唴杈硅窛銆佽竟妗嗙瓑鏍峰紡
+ */
+defineOptions({ name: 'ComponentContainer' })
+
+type DiyComponentWithStyle = DiyComponent<any> & { property: { style?: ComponentStyle } }
+const props = defineProps({
+ component: object<DiyComponentWithStyle>().isRequired,
+ active: propTypes.bool.def(false),
+ canMoveUp: propTypes.bool.def(false),
+ canMoveDown: propTypes.bool.def(false),
+ showToolbar: propTypes.bool.def(true)
+})
+
+/**
+ * 缁勪欢鏍峰紡
+ */
+const style = computed(() => {
+ let componentStyle = props.component.property.style
+ if (!componentStyle) {
+ return {}
+ }
+ return {
+ marginTop: `${componentStyle.marginTop || 0}px`,
+ marginBottom: `${componentStyle.marginBottom || 0}px`,
+ marginLeft: `${componentStyle.marginLeft || 0}px`,
+ marginRight: `${componentStyle.marginRight || 0}px`,
+ paddingTop: `${componentStyle.paddingTop || 0}px`,
+ paddingRight: `${componentStyle.paddingRight || 0}px`,
+ paddingBottom: `${componentStyle.paddingBottom || 0}px`,
+ paddingLeft: `${componentStyle.paddingLeft || 0}px`,
+ borderTopLeftRadius: `${componentStyle.borderTopLeftRadius || 0}px`,
+ borderTopRightRadius: `${componentStyle.borderTopRightRadius || 0}px`,
+ borderBottomRightRadius: `${componentStyle.borderBottomRightRadius || 0}px`,
+ borderBottomLeftRadius: `${componentStyle.borderBottomLeftRadius || 0}px`,
+ overflow: 'hidden',
+ background:
+ componentStyle.bgType === 'color' ? componentStyle.bgColor : `url(${componentStyle.bgImg})`
+ }
+})
+
+const emits = defineEmits<{
+ (e: 'move', direction: number): void
+ (e: 'copy'): void
+ (e: 'delete'): void
+}>()
+
+/**
+ * 绉诲姩缁勪欢
+ * @param direction 绉诲姩鏂瑰悜
+ */
+const handleMoveComponent = (direction: number) => {
+ emits('move', direction)
+}
+
+/**
+ * 澶嶅埗缁勪欢
+ */
+const handleCopyComponent = () => {
+ emits('copy')
+}
+
+/**
+ * 鍒犻櫎缁勪欢
+ */
+const handleDeleteComponent = () => {
+ emits('delete')
+}
+</script>
+
+<style scoped lang="scss">
+$active-border-width: 2px;
+$hover-border-width: 1px;
+$name-position: -85px;
+$toolbar-position: -55px;
+
+/* 缁勪欢 */
+.component {
+ position: relative;
+ cursor: move;
+
+ .component-wrap {
+ position: absolute;
+ top: 0;
+ left: -$active-border-width;
+ display: block;
+ width: 100%;
+ height: 100%;
+
+ /* 榧犳爣鏀惧埌缁勪欢涓婃椂 */
+ &:hover {
+ border: $hover-border-width dashed var(--el-color-primary);
+ box-shadow: 0 0 5px 0 rgb(24 144 255 / 30%);
+
+ .component-name {
+ top: $hover-border-width;
+
+ /* 闃叉鍔犱簡杈规涔嬪悗锛屼綅缃Щ鍔� */
+ left: $name-position - $hover-border-width;
+ }
+ }
+
+ /* 宸︿晶锛氱粍浠跺悕绉� */
+ .component-name {
+ position: absolute;
+ top: $active-border-width;
+ left: $name-position;
+ display: block;
+ width: 80px;
+ height: 25px;
+ font-size: 12px;
+ color: #6a6a6a;
+ line-height: 25px;
+ text-align: center;
+ background: #fff;
+ box-shadow:
+ 0 0 4px #00000014,
+ 0 2px 6px #0000000f,
+ 0 4px 8px 2px #0000000a;
+
+ /* 鍙充晶灏忎笁瑙� */
+ &::after {
+ position: absolute;
+ top: 7.5px;
+ right: -10px;
+ width: 0;
+ height: 0;
+ border: 5px solid transparent;
+ border-left-color: #fff;
+ content: ' ';
+ }
+ }
+
+ /* 鍙充晶锛氱粍浠舵搷浣滃伐鍏锋爮 */
+ .component-toolbar {
+ position: absolute;
+ top: 0;
+ right: $toolbar-position;
+ display: none;
+
+ /* 宸︿晶灏忎笁瑙� */
+ &::before {
+ position: absolute;
+ top: 10px;
+ left: -10px;
+ width: 0;
+ height: 0;
+ border: 5px solid transparent;
+ border-right-color: #2d8cf0;
+ content: ' ';
+ }
+ }
+ }
+
+ /* 缁勪欢閫変腑鏃� */
+ &.active {
+ margin-bottom: 4px;
+
+ .component-wrap {
+ margin-bottom: $active-border-width + $active-border-width;
+ border: $active-border-width solid var(--el-color-primary) !important;
+ box-shadow: 0 0 10px 0 rgb(24 144 255 / 30%);
+
+ .component-name {
+ top: 0 !important;
+
+ /* 闃叉鍔犱簡杈规涔嬪悗锛屼綅缃Щ鍔� */
+ left: $name-position - $active-border-width !important;
+ color: #fff;
+ background: var(--el-color-primary);
+
+ &::after {
+ border-left-color: var(--el-color-primary);
+ }
+ }
+
+ .component-toolbar {
+ display: block;
+ }
+ }
+ }
+}
+</style>
--
Gitblit v1.8.0