31
This commit is contained in:
@@ -38,13 +38,17 @@ const isRowLayout = computed(() => {
|
||||
return dragStore.selectedNode?.type === 'er'
|
||||
})
|
||||
|
||||
// 是否是跨类型拖放
|
||||
const isCrossType = computed(() => dragStore.isCrossTypeDrop)
|
||||
|
||||
// 获取方向文本
|
||||
const getDirectionText = (direction: DropDirection): string => {
|
||||
const texts: Record<DropDirection, string> = {
|
||||
'top': '移动至上方',
|
||||
'bottom': '移动至下方',
|
||||
'left': '移动至左侧',
|
||||
'right': '移动至右侧'
|
||||
'right': '移动至右侧',
|
||||
'inside': '放入其中'
|
||||
}
|
||||
return texts[direction]
|
||||
}
|
||||
@@ -55,7 +59,8 @@ const getDirectionIcon = (direction: DropDirection): string => {
|
||||
'top': '⬆',
|
||||
'bottom': '⬇',
|
||||
'left': '⬅',
|
||||
'right': '➡'
|
||||
'right': '➡',
|
||||
'inside': '⬇️⤵️' // 放入图标
|
||||
}
|
||||
return icons[direction]
|
||||
}
|
||||
@@ -66,7 +71,11 @@ const getDirectionIcon = (direction: DropDirection): string => {
|
||||
<div
|
||||
v-if="dragStore.isDragging && dragStore.selectedNode"
|
||||
class="drop-zone-container"
|
||||
:class="{ 'is-row': isRowLayout, 'is-col': !isRowLayout }"
|
||||
:class="{
|
||||
'is-row': isRowLayout && !isCrossType,
|
||||
'is-col': !isRowLayout && !isCrossType,
|
||||
'is-inside': isCrossType
|
||||
}"
|
||||
:style="zoneStyle"
|
||||
>
|
||||
<div
|
||||
@@ -137,6 +146,32 @@ const getDirectionIcon = (direction: DropDirection): string => {
|
||||
border-left: 2px solid rgba(64, 158, 255, 0.8);
|
||||
}
|
||||
|
||||
/* 放入内部区域 */
|
||||
.drop-zone-container.is-inside {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.zone-inside {
|
||||
background: rgba(103, 194, 58, 0.15);
|
||||
border: 3px dashed rgba(103, 194, 58, 0.6);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.zone-inside.is-active {
|
||||
background: rgba(103, 194, 58, 0.3);
|
||||
border-color: rgba(103, 194, 58, 0.9);
|
||||
}
|
||||
|
||||
.zone-inside .zone-icon,
|
||||
.zone-inside .zone-text {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.zone-inside.is-active .zone-icon,
|
||||
.zone-inside.is-active .zone-text {
|
||||
color: #85ce61;
|
||||
}
|
||||
|
||||
.drop-zone:hover,
|
||||
.drop-zone.is-active {
|
||||
background: rgba(64, 158, 255, 0.25);
|
||||
|
||||
@@ -8,8 +8,11 @@ const TEMPLATE_SERVICE_URL = 'http://localhost:3001'
|
||||
|
||||
/**
|
||||
* 拖放方向
|
||||
* - top/bottom: el-row 的上下方
|
||||
* - left/right: el-col 的左右方
|
||||
* - inside: 放入内部(跨类型拖放时)
|
||||
*/
|
||||
export type DropDirection = 'top' | 'bottom' | 'left' | 'right'
|
||||
export type DropDirection = 'top' | 'bottom' | 'left' | 'right' | 'inside'
|
||||
|
||||
/**
|
||||
* 拖拽源信息
|
||||
@@ -245,6 +248,22 @@ export const useDragStore = defineStore('drag', () => {
|
||||
hoverDirection.value = direction
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为跨类型拖放(源和目标类型不同)
|
||||
*/
|
||||
const isCrossTypeDrop = computed(() => {
|
||||
if (!dragSource.value || !selectedNode.value) return false
|
||||
|
||||
// 只有画布内元素拖放才考虑跨类型
|
||||
if (dragSource.value.type !== 'canvas-element') return false
|
||||
|
||||
const sourceType = dragSource.value.elementType
|
||||
const targetType = selectedNode.value.type
|
||||
|
||||
// er 拖到 ec 或 ec 拖到 er 都是跨类型
|
||||
return sourceType !== targetType
|
||||
})
|
||||
|
||||
/**
|
||||
* 根据鼠标位置自动计算拖放方向
|
||||
* @param mouseX 鼠标X坐标
|
||||
@@ -253,6 +272,12 @@ export const useDragStore = defineStore('drag', () => {
|
||||
const updateDirectionFromMouse = (mouseX: number, mouseY: number) => {
|
||||
if (!selectedNode.value?.element) return
|
||||
|
||||
// 跨类型拖放时,始终显示 "inside"
|
||||
if (isCrossTypeDrop.value) {
|
||||
hoverDirection.value = 'inside'
|
||||
return
|
||||
}
|
||||
|
||||
const rect = selectedNode.value.element.getBoundingClientRect()
|
||||
const isRow = selectedNode.value.type === 'er'
|
||||
|
||||
@@ -365,7 +390,8 @@ export const useDragStore = defineStore('drag', () => {
|
||||
'top': '上方',
|
||||
'bottom': '下方',
|
||||
'left': '左侧',
|
||||
'right': '右侧'
|
||||
'right': '右侧',
|
||||
'inside': '内部'
|
||||
}
|
||||
|
||||
let sourceName = ''
|
||||
@@ -384,6 +410,11 @@ export const useDragStore = defineStore('drag', () => {
|
||||
const getDropDirections = computed((): DropDirection[] => {
|
||||
if (!selectedNode.value) return []
|
||||
|
||||
// 跨类型拖放:显示"放入内部"
|
||||
if (isCrossTypeDrop.value) {
|
||||
return ['inside']
|
||||
}
|
||||
|
||||
// el-row 显示上下
|
||||
if (selectedNode.value.type === 'er') {
|
||||
return ['top', 'bottom']
|
||||
@@ -403,6 +434,7 @@ export const useDragStore = defineStore('drag', () => {
|
||||
lastDropRecord,
|
||||
dropRecords,
|
||||
getDropDirections,
|
||||
isCrossTypeDrop,
|
||||
|
||||
// 方法
|
||||
startDragFromComponentList,
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">
|
||||
<div class="design-component">右侧列1</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<div class="design-component">右侧列2</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-col :span="12">
|
||||
<div class="design-component">右侧列1</div>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user