|
@@ -159,6 +159,7 @@ export default {
|
|
|
getBookUnifiedAttr: () => this.book_unified_attrib,
|
|
getBookUnifiedAttr: () => this.book_unified_attrib,
|
|
|
getTitleList: () => this.title_list,
|
|
getTitleList: () => this.title_list,
|
|
|
getProjectResourcePopedom: () => this.projectResourcePopedom,
|
|
getProjectResourcePopedom: () => this.projectResourcePopedom,
|
|
|
|
|
+ moveComponentDragStart: this.dragStart,
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
props: {
|
|
props: {
|
|
@@ -190,6 +191,8 @@ export default {
|
|
|
content_group_row_list: [], // 行分组id列表
|
|
content_group_row_list: [], // 行分组id列表
|
|
|
gridBorderColorList: ['#3fc7cc', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#d863ff', '#724fff'], // 网格边框颜色列表
|
|
gridBorderColorList: ['#3fc7cc', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#d863ff', '#724fff'], // 网格边框颜色列表
|
|
|
curType: 'divider',
|
|
curType: 'divider',
|
|
|
|
|
+ curParams: {}, // 当前组件参数
|
|
|
|
|
+ scrollInterval: null, // 滚动定时器
|
|
|
componentList,
|
|
componentList,
|
|
|
curRow: -2,
|
|
curRow: -2,
|
|
|
curCol: -1,
|
|
curCol: -1,
|
|
@@ -947,18 +950,20 @@ export default {
|
|
|
/**
|
|
/**
|
|
|
* 拖拽开始
|
|
* 拖拽开始
|
|
|
* 用点击模拟拖拽
|
|
* 用点击模拟拖拽
|
|
|
- * @param {MouseEvent} event
|
|
|
|
|
- * @param {string} type
|
|
|
|
|
|
|
+ * @param {MouseEvent} event 鼠标事件
|
|
|
|
|
+ * @param {string} type 组件类型
|
|
|
|
|
+ * @param {object} params 组件参数
|
|
|
*/
|
|
*/
|
|
|
- dragStart(event, type) {
|
|
|
|
|
|
|
+ dragStart(event, type, params = {}) {
|
|
|
// 获取鼠标位置
|
|
// 获取鼠标位置
|
|
|
const { clientX, clientY } = event;
|
|
const { clientX, clientY } = event;
|
|
|
document.body.style.userSelect = 'none'; // 禁止选中文本
|
|
document.body.style.userSelect = 'none'; // 禁止选中文本
|
|
|
this.drag.dragging = true;
|
|
this.drag.dragging = true;
|
|
|
this.curType = type;
|
|
this.curType = type;
|
|
|
|
|
+ this.curParams = params;
|
|
|
// 在鼠标位置创建一个拖拽元素
|
|
// 在鼠标位置创建一个拖拽元素
|
|
|
const dragging = document.createElement('div');
|
|
const dragging = document.createElement('div');
|
|
|
- dragging.className = 'canvas-dragging';
|
|
|
|
|
|
|
+ dragging.className = `canvas-dragging${type === 'component' ? ' component-dragging' : ''}`;
|
|
|
this.drag.clientX = clientX;
|
|
this.drag.clientX = clientX;
|
|
|
this.drag.clientY = clientY;
|
|
this.drag.clientY = clientY;
|
|
|
document.body.appendChild(dragging);
|
|
document.body.appendChild(dragging);
|
|
@@ -980,6 +985,31 @@ export default {
|
|
|
this.enterCanvas = isInsideCanvas;
|
|
this.enterCanvas = isInsideCanvas;
|
|
|
if (!isInsideCanvas) return;
|
|
if (!isInsideCanvas) return;
|
|
|
|
|
|
|
|
|
|
+ // 当移动组件时,如果鼠标位置距离画布上下边距小于 20px,则自动滚动画布,做一个定时器每隔 100ms 判断一次,直到鼠标位置距离边距大于 20px 或者离开画布
|
|
|
|
|
+ if (this.curType === 'component') {
|
|
|
|
|
+ const middleDom = document.querySelector('.create-middle');
|
|
|
|
|
+ // 获取 middleDom 相对于 event 的位置
|
|
|
|
|
+ const middleRect = middleDom.getBoundingClientRect();
|
|
|
|
|
+ const middleHeight = middleRect.height;
|
|
|
|
|
+ const offsetTop = clientY - middleRect.top;
|
|
|
|
|
+ const offsetBottom = middleRect.bottom - clientY;
|
|
|
|
|
+ if (this.scrollInterval) {
|
|
|
|
|
+ clearInterval(this.scrollInterval);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (offsetTop < 20) {
|
|
|
|
|
+ this.scrollInterval = setInterval(() => {
|
|
|
|
|
+ middleDom.scrollTop = Math.max(0, middleDom.scrollTop - 10);
|
|
|
|
|
+ }, 10);
|
|
|
|
|
+ } else if (offsetBottom < 20) {
|
|
|
|
|
+ this.scrollInterval = setInterval(() => {
|
|
|
|
|
+ middleDom.scrollTop = Math.min(middleDom.scrollHeight - middleHeight, middleDom.scrollTop + 10);
|
|
|
|
|
+ }, 10);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ clearInterval(this.scrollInterval);
|
|
|
|
|
+ this.scrollInterval = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.showRecentLine(clientX, clientY);
|
|
this.showRecentLine(clientX, clientY);
|
|
|
},
|
|
},
|
|
|
/**
|
|
/**
|
|
@@ -1029,23 +1059,88 @@ export default {
|
|
|
this.drag.dragging = false;
|
|
this.drag.dragging = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (this.scrollInterval) {
|
|
|
|
|
+ clearInterval(this.scrollInterval);
|
|
|
|
|
+ this.scrollInterval = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!this.isEdit) return;
|
|
if (!this.isEdit) return;
|
|
|
|
|
|
|
|
if (this.enterCanvas) {
|
|
if (this.enterCanvas) {
|
|
|
|
|
+ if (this.curType === 'component') {
|
|
|
|
|
+ this.handleComponentMove();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (this.curRow >= -1 && this.curCol <= -1) {
|
|
if (this.curRow >= -1 && this.curCol <= -1) {
|
|
|
this.calculateRowInsertedObject();
|
|
this.calculateRowInsertedObject();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (this.curRow >= -1 && this.curCol > -1 && this.curGrid <= -1) {
|
|
if (this.curRow >= -1 && this.curCol > -1 && this.curGrid <= -1) {
|
|
|
|
|
+ // 当拖拽组件和放置位置在同一列内,且行内组件数量为 1,将 curRow 减 1,才能正确插入
|
|
|
|
|
+ if ('col' in this.curParams) {
|
|
|
|
|
+ const { col, row, rowNum } = this.curParams;
|
|
|
|
|
+ if (col === this.curCol && row === this.curRow && rowNum === 1) {
|
|
|
|
|
+ this.curRow = Math.max(0, this.curRow - 1);
|
|
|
|
|
+ this.calculateRowInsertedObject();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
this.calculateColObject();
|
|
this.calculateColObject();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (this.curRow >= -1 && this.curCol > -1 && this.curGrid > -1) {
|
|
if (this.curRow >= -1 && this.curCol > -1 && this.curGrid > -1) {
|
|
|
|
|
+ if ('col' in this.curParams) {
|
|
|
|
|
+ const { col, row, grid } = this.curParams;
|
|
|
|
|
+
|
|
|
|
|
+ // 当拖拽组件和放置位置在同一列内,将 curGrid 减 1,对应上面的删除组件,才能正确插入
|
|
|
|
|
+ if (col === this.curCol && row === this.curRow && grid < this.curGrid) {
|
|
|
|
|
+ this.curGrid = Math.max(0, this.curGrid - 1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 当拖拽组件和放置位置在同一列内,且行内组件数量为 1,将 curRow 减 1,才能正确插入
|
|
|
|
|
+ if (col === this.curCol && row === this.curRow && grid === this.curGrid) {
|
|
|
|
|
+ this.curRow = Math.max(0, this.curRow - 1);
|
|
|
|
|
+ this.calculateRowInsertedObject();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.calculateGridObject();
|
|
this.calculateGridObject();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ this.curType = '';
|
|
|
|
|
+ this.curParams = {};
|
|
|
this.enterCanvas = false;
|
|
this.enterCanvas = false;
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 处理组件移动
|
|
|
|
|
+ * 组件拖拽移动后,先删除组件,再根据拖拽位置计算插入行、列、格子
|
|
|
|
|
+ */
|
|
|
|
|
+ handleComponentMove() {
|
|
|
|
|
+ const component = this.findChildComponentByKey(`grid-${this.curParams.id}`);
|
|
|
|
|
+ const data = component?.data;
|
|
|
|
|
+ this.curType = data?.type || 'select';
|
|
|
|
|
+ let col = component?.$attrs['data-col'];
|
|
|
|
|
+ let row = component?.$attrs['data-row'];
|
|
|
|
|
+ let grid = component?.$attrs['data-grid'];
|
|
|
|
|
+ let rowNum = 0; // 当前行组件数量
|
|
|
|
|
+ this.data.row_list[row].col_list.forEach((item) => {
|
|
|
|
|
+ rowNum += item.grid_list.length;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.curParams = {
|
|
|
|
|
+ ...this.curParams,
|
|
|
|
|
+ col,
|
|
|
|
|
+ row,
|
|
|
|
|
+ grid,
|
|
|
|
|
+ rowNum,
|
|
|
|
|
+ };
|
|
|
|
|
+ this.deleteComponent(this.curParams.id);
|
|
|
|
|
+ },
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算行样式
|
|
|
|
|
+ * @param {number} i 行索引
|
|
|
|
|
+ */
|
|
|
computedRowStyle(i) {
|
|
computedRowStyle(i) {
|
|
|
let row = this.data.row_list[i];
|
|
let row = this.data.row_list[i];
|
|
|
let col = row.col_list;
|
|
let col = row.col_list;
|
|
@@ -1071,7 +1166,7 @@ export default {
|
|
|
* 计算网格插入的对象
|
|
* 计算网格插入的对象
|
|
|
*/
|
|
*/
|
|
|
calculateGridObject() {
|
|
calculateGridObject() {
|
|
|
- const id = `ID-${getRandomNumber(12, true)}`;
|
|
|
|
|
|
|
+ const id = this.curParams?.id || `ID-${getRandomNumber(12, true)}`;
|
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
|
|
|
|
|
|
let row = this.data.row_list[this.curRow];
|
|
let row = this.data.row_list[this.curRow];
|
|
@@ -1127,7 +1222,7 @@ export default {
|
|
|
* 计算列插入的对象
|
|
* 计算列插入的对象
|
|
|
*/
|
|
*/
|
|
|
calculateColObject() {
|
|
calculateColObject() {
|
|
|
- const id = `ID-${getRandomNumber(12, true)}`;
|
|
|
|
|
|
|
+ const id = this.curParams?.id || `ID-${getRandomNumber(12, true)}`;
|
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
|
const col_id = `C${getRandomNumber(8, true)}`;
|
|
const col_id = `C${getRandomNumber(8, true)}`;
|
|
|
|
|
|
|
@@ -1164,7 +1259,7 @@ export default {
|
|
|
* 计算行插入的对象
|
|
* 计算行插入的对象
|
|
|
*/
|
|
*/
|
|
|
calculateRowInsertedObject() {
|
|
calculateRowInsertedObject() {
|
|
|
- const id = `ID-${getRandomNumber(12, true)}`;
|
|
|
|
|
|
|
+ const id = this.curParams?.id || `ID-${getRandomNumber(12, true)}`;
|
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
const letter = `L${getRandomNumber(6, true)}`;
|
|
|
const row_id = `R${getRandomNumber(6, true)}`;
|
|
const row_id = `R${getRandomNumber(6, true)}`;
|
|
|
const col_id = `C${getRandomNumber(8, true)}`;
|
|
const col_id = `C${getRandomNumber(8, true)}`;
|
|
@@ -1655,5 +1750,10 @@ export default {
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
opacity: 0.5;
|
|
opacity: 0.5;
|
|
|
transform: translate(-40%, -40%);
|
|
transform: translate(-40%, -40%);
|
|
|
|
|
+
|
|
|
|
|
+ &.component-dragging {
|
|
|
|
|
+ background-color: #f9ffe0;
|
|
|
|
|
+ border-color: #f9ffe0;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|