mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-06 17:09:08 +08:00
feat(manager): 画布楼层加名称标签与悬浮操作条
- 每楼层左上角显示组件名标签 - 选中楼层右侧竖排操作条:上移/下移/复制/删除/隐藏,替代原右上角关闭图标 - 隐藏楼层变暗并显示已隐藏蒙层,hidden 随 pageData 保存
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div class="list">
|
||||
<div class="floor-name">{{ element.name || element.type }}</div>
|
||||
<component
|
||||
v-if="templates[element.type]"
|
||||
class="component"
|
||||
@@ -60,15 +61,24 @@
|
||||
>
|
||||
未知组件「{{ element.type }}」已下线,点击删除
|
||||
</div>
|
||||
<el-icon
|
||||
v-if="selected == index"
|
||||
@click="closeComponent(index)"
|
||||
class="close"
|
||||
:size="25"
|
||||
color="#e1251b"
|
||||
>
|
||||
<CircleClose />
|
||||
</el-icon>
|
||||
<div v-if="element.hidden" class="floor-hidden-mask">已隐藏</div>
|
||||
<div v-if="selected == index" class="floor-tools">
|
||||
<el-icon
|
||||
:class="{ disabled: index === 0 }"
|
||||
@click="moveComponent(index, -1)"
|
||||
><Top
|
||||
/></el-icon>
|
||||
<el-icon
|
||||
:class="{ disabled: index === contentData.list.length - 1 }"
|
||||
@click="moveComponent(index, 1)"
|
||||
><Bottom
|
||||
/></el-icon>
|
||||
<el-icon @click="copyComponent(index)"><CopyDocument /></el-icon>
|
||||
<el-icon @click="closeComponent(index)"><Delete /></el-icon>
|
||||
<el-icon @click="toggleHide(index)"
|
||||
><View v-if="!element.hidden" /><Hide v-else
|
||||
/></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
@@ -88,7 +98,6 @@
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
CircleClose,
|
||||
Picture,
|
||||
PictureFilled,
|
||||
Document,
|
||||
@@ -110,6 +119,12 @@ import {
|
||||
Crop,
|
||||
Minus,
|
||||
EditPen,
|
||||
Top,
|
||||
Bottom,
|
||||
CopyDocument,
|
||||
Delete,
|
||||
View,
|
||||
Hide,
|
||||
} from "@element-plus/icons-vue";
|
||||
import templates from "./template/index";
|
||||
import Draggable from "vuedraggable";
|
||||
@@ -121,7 +136,6 @@ export default {
|
||||
components: {
|
||||
Draggable,
|
||||
decorate,
|
||||
CircleClose,
|
||||
Picture,
|
||||
PictureFilled,
|
||||
Document,
|
||||
@@ -143,6 +157,12 @@ export default {
|
||||
Crop,
|
||||
Minus,
|
||||
EditPen,
|
||||
Top,
|
||||
Bottom,
|
||||
CopyDocument,
|
||||
Delete,
|
||||
View,
|
||||
Hide,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -268,6 +288,29 @@ export default {
|
||||
console.warn(`[page-decoration] 未知组件类型: ${element.type}`);
|
||||
this.closeComponent(index);
|
||||
},
|
||||
// 上移/下移楼层
|
||||
moveComponent(index, dir) {
|
||||
const target = index + dir;
|
||||
if (target < 0 || target >= this.contentData.list.length) return;
|
||||
const list = this.contentData.list;
|
||||
[list[index], list[target]] = [list[target], list[index]];
|
||||
this.selected = target;
|
||||
this.handleComponent(this.contentData.list[target], target);
|
||||
},
|
||||
// 复制楼层
|
||||
copyComponent(index) {
|
||||
const cloned = JSON.parse(JSON.stringify(this.contentData.list[index]));
|
||||
const key = Date.now() + "_" + Math.ceil(Math.random() * 99999);
|
||||
cloned.key = key;
|
||||
cloned.model = cloned.type + "_" + key;
|
||||
this.contentData.list.splice(index + 1, 0, cloned);
|
||||
this.handleComponent(this.contentData.list[index + 1], index + 1);
|
||||
},
|
||||
// 隐藏/显示楼层(渲染端跳过 hidden 楼层)
|
||||
toggleHide(index) {
|
||||
const item = this.contentData.list[index];
|
||||
item.hidden = !item.hidden;
|
||||
},
|
||||
// 右侧栏回调
|
||||
handleDrawer(val) {
|
||||
let newIndex = this.selected;
|
||||
|
||||
@@ -124,11 +124,57 @@
|
||||
.list {
|
||||
position: relative;
|
||||
}
|
||||
.close {
|
||||
.floor-name {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 10px;
|
||||
z-index: 99;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
z-index: 60;
|
||||
background: #ffffff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
padding: 2px 8px;
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
pointer-events: none;
|
||||
}
|
||||
.floor-tools {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #ffffff;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
padding: 4px 0;
|
||||
.el-icon {
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
color: #606266;
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
&.disabled {
|
||||
color: #dcdfe6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
.floor-hidden-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 50;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
.unknown-component {
|
||||
padding: 16px 10px;
|
||||
|
||||
Reference in New Issue
Block a user