只需要关注sortablejs的api方面使用,业务方面可以忽略
import Sortable from "sortablejs";
import {
generateRawInfo,
getSplitTag,
findCodeElemNode,
findRawVueInfo,
insertPresetAttribute,
replaceRowID,
} from "@/utils/forCode";
import { html2Json } from "@/libs/bundle-html2json-esm";
import { getRawComponentContent, getRawComponentKey } from "@/utils/common";
import { addDiyFileByDragId } from "@/utils/dragComponentUtil/index.js";
import { setAnyTable } from "@/libs/tableEditor.js";
import { setDropAfterPos } from "./move-line.js";
import { drawLine } from "@/utils/lineHelper";
import { store as _store } from "@/libs/store.js";
import { cloneDeep, uniqBy } from "lodash-es";
const handleObj = { key: "bob", entity: null, containerDom: null, vccElKey: null };
const whiteListKeys = ["el-card", "el-table"]; //含有子节点的必须提前写在这
function loopDom(childNodes) {
childNodes.forEach((ele) => {
let key = geVccElKey(ele);
if (ele.nodeName.includes("#")) {
return;
}
if (!key) {
return;
}
if (ele.classList.contains("actionWrap")) {
return;
}
Sortable.create(ele, commonOps);
if (ele.childNodes && ele.childNodes.length) {
loopDom(ele.childNodes);
}
});
}
const setData = (dataTransfer, element) => {
const raw = generateRawInfo(element);
const str = `${element.localName}${getSplitTag()}${
element.innerText
}${getSplitTag()}${0}${getSplitTag()}${element.style.cssText}${getSplitTag()}${JSON.stringify(
raw
)}`;
dataTransfer.setData("text/plain", str);
};
const newMerge = (o1, o2, currentPointPositionAfterIndex = -1, fn = null) => {
if (o1 && o2) {
if (!o1["__children"]) {
o1["__children"] = [];
}
if (currentPointPositionAfterIndex > -1) {
o1["__children"].splice(currentPointPositionAfterIndex, 0, o2);
} else {
o1["__children"].push(o2);
}
o2.__proto__ = { parentCodeNode: o1 };
if (fn) {
fn();
}
}
};
const onEnd = async (event) => {
const {
originalEvent: { dataTransfer },
} = event;
const renderControlPanel = window.mainPanelProvider.getControlPanelRoot();
let container = renderControlPanel.firstChild; //querySelector(`[lc_id="container"]`);
let json = await html2Json(container.innerHTML);
const data = dataTransfer.getData("text/plain");
const [, , , , rawInfo] = data.split(getSplitTag());
console.log("转换得原始数据:", json);
if (!rawInfo || rawInfo == "undefined") {
console.log('rawInfo == "undefined":', rawInfo);
return;
}
const newDropObj = JSON.parse(rawInfo);
console.log("newDropObj:", newDropObj);
//判断lc_id是否是diy组件并import
let diy_lc_id = getRawComponentContent(newDropObj).lc_id;
addDiyFileByDragId(diy_lc_id);
window.mainPanelProvider.removeSame(newDropObj);
// 插入预设属性
insertPresetAttribute(newDropObj);
// 使新拖入的代码与原来的做脱离
replaceRowID(newDropObj, "");
// 更新代码结构关系
const codeTargetElement = findCodeElemNode(window.mainPanelProvider.currentPointDropInfo.target);
if (codeTargetElement) {
let temp = findRawVueInfo(codeTargetElement);
console.log("渲染容器:", getRawComponentContent(temp));
window.mainPanelProvider.backup();
newMerge(
getRawComponentContent(temp),
newDropObj,
window.mainPanelProvider.currentPointDropInfo.index,
() => {
window.mainPanelProvider.sustainedMarkElement(getRawComponentContent(newDropObj).lc_id);
window.mainPanelProvider.eventEmitter.emit("onMerged");
}
);
//任意拖拽
window.mainPanelProvider.isAnyDrag
? setDropAfterPos(originalEvent.clientX, originalEvent.clientY, newDropObj)
: null;
setAnyTable(newDropObj); //设置任意表格
window.mainPanelProvider.render(window.mainPanelProvider._rawDataStructure);
}
};
const onMove = (/**Event*/ event, /**Event*/ originalEvent) => {
drawLine(event, originalEvent);
};
const isEmpty = (obj) => {
return JSON.stringify(obj) === "{}";
};
//防止内存爆
const changeObjectToTree = (data, attr = "__children", sub = "__children", label = "label") => {
let newArr = [];
for (let i = 0; i < data.length; i++) {
const key = getRawComponentKey(data[i]);
let item = cloneDeep(data[i][key]);
let oldInfo = cloneDeep(data[i][key]);
if (item) {
newArr[i] = {
[key]: {
...item,
[sub]: [],
},
};
if (oldInfo[attr] && oldInfo[attr].length) {
newArr[i][key][sub] = changeObjectToTree(oldInfo[attr], attr, sub);
}
}
}
return newArr;
};
const isChildrenEmpty = (lcidObj, parentLc_id) => {
for (const key in lcidObj) {
const obj = lcidObj[key];
if (!obj) {
return;
}
// debugger;
if (!obj || !obj.children || isEmpty(obj.children)) {
lcidObj[parentLc_id] = null;
} else {
//debugger;
let k = Object.keys(obj.children)[0];
let o1 = obj.children[k];
let k1 = Object.keys(o1)[0];
isChildrenEmpty(o1, k1);
}
}
};
//白名单key
const whiteListKeyFn = (obj) => {
let key = getRawComponentKey(tree[obj.lc_id]);
let isClear = whiteListKeys.some((k) => {
return k === key;
});
isClear ? null : (obj.__children = []);
};
const setLcidChildren = (objC, template, treeObjC = null) => {
for (let lc_id in objC) {
let obj = objC[lc_id];
let treeObj = tree[lc_id];
let o1 = getRawComponentContent(treeObj);
whiteListKeyFn(o1);
if (treeObjC) {
treeObjC.__children.push(treeObj);
} else {
template.push(treeObj);
}
if (obj && obj.children && !isEmpty(obj.children)) {
for (let num in obj.children) {
let lcidObj = obj.children[num];
setLcidChildren(lcidObj, template, o1);
}
}
}
};
//获取最新模板
const getTemplate = (lcidObj, template, treeObj = null) => {
for (let num in lcidObj) {
let obj = lcidObj[num];
setLcidChildren(obj, template, treeObj);
}
};
const getLcids = (children, lcidObj, parentLc_id = null, parentIndex = null) => {
//debugger;
children.length &&
children.forEach((dom, index) => {
//debugger;
if (dom.classList.contains("actionWrap")) {
return;
}
let lc_id = dom.getAttribute("lc_id");
if (lc_id) {
// debugger;
if (parentLc_id) {
if (dom.children && dom.children.length) {
let obj = {};
obj[lc_id] = { children: {} };
if (!lcidObj[parentLc_id] || isEmpty(lcidObj[parentLc_id])) {
lcidObj[parentLc_id] = { children: {} };
}
lcidObj[parentLc_id].children[index] = obj;
let childrendoms = [].slice.call(dom.children);
getLcids(childrendoms, lcidObj[parentLc_id].children[index], lc_id, index);
} else {
//debugger;
let obj = {};
obj[lc_id] = null;
let parentChild = lcidObj[parentLc_id].children;
let parentChildLen = Object.keys(parentChild).length;
parentChild[parentChildLen] = obj;
console.log("parentChildLen:", parentChildLen);
console.log("parentChild:", parentChild);
}
} else {
if (dom.children && dom.children.length) {
let obj = {};
obj[lc_id] = { children: {} };
lcidObj[index] = obj;
let childrendoms = [].slice.call(dom.children);
getLcids(childrendoms, lcidObj[index], lc_id, index);
} else {
let obj = {};
obj[lc_id] = null;
lcidObj[index] = obj;
}
}
} else {
isChildrenEmpty(lcidObj, parentLc_id);
}
});
};
const geVccElKey = (target) => {
try {
const __rawVueInfo__ = window.tree[target.attributes.lc_id.nodeValue];
const key = getRawComponentKey(__rawVueInfo__);
return key;
} catch (error) {
return null;
}
};
export const leftOps = {
animation: 200,
group: { name: "group", put: false, pull: "clone" },
sort: false,
easing: "cubic-bezier(1, 0, 0, 1)",
chosenClass: "mark-element-unit",
setData,
onStart: function (event) {
_store.commit("setIsDrop", false);
},
};
export const commonOps = {
animation: 200,
handle: ".copyIcon", //必须搭配draggable属性才会生效喔
draggable: ".mark-element",
group: {
name: "group",
/*
因为用了filter属性,根据你自己的需求注释掉
put: () => {
if (handleObj.vccElKey != "div") {
return true;
}
return false;
},
pull: () => {
if (!handleObj.vccElKey) {
return false;
}
return true;
},*/
},
filter: (evt, target) => {
let key = geVccElKey(target);
if (key) {
return false;
}
return true;
},
easing: "cubic-bezier(1, 0, 0, 1)",
setData,
onStart: function (event) {
window.mainPanelProvider.backup();
const { item } = event;
let key = geVccElKey(item);
handleObj.vccElKey = key;
_store.commit("setIsDrop", true);
},
onEnd: async function (event) {
if (!handleObj.vccElKey) {
return;
}
/*let lcidObj = {
0: {
"42qryko5ba": {
children: {
0: {
kdc7rq479g: null,
},
},
},
},
1: {
"2fdjr1n7w2": {
children: {
0: {
"8jdoyxe938": null,
},
},
},
},
2: {
w9tr5ojf1f: {
children: {
0: {
wriaw2ggwp: {
children: {
0: {
kdc7rq479g: null,
},
},
},
},
},
},
},
3: {
kdc7rq479g: null,
},
};*/
let lcidObj = {};
let template = [];
const renderControlPanel = window.mainPanelProvider.getControlPanelRoot();
let wrapdom = renderControlPanel.firstChild;
let wrapdoms = [].slice.call(wrapdom.children);
getLcids(wrapdoms, lcidObj);
getTemplate(lcidObj, template);
let temp = changeObjectToTree(template);
console.log("顺序", lcidObj);
console.log("模板", template);
console.log("最终模板", temp);
setTimeout(() => {
window.tree.container.div.__children = temp;
let cloneR = window.tree.root; //cloneDeep(window.tree.root);
let obj0 = cloneR.template.__children[0];
obj0.div.__children = temp;
window.mainPanelProvider.render(cloneR);
}, 0);
},
};
export default function sortableInit() {
handleObj.containerDom = document.querySelector(`[lc_id="container"]`);
handleObj.entity = Sortable.create(handleObj.containerDom, commonOps);
loopDom(handleObj.containerDom.childNodes);
}