1.首先说树状结构的实现
我直接推一手链接,直接用他的最终源码就可以
HTML&CSS中的树形结构图_html树状结构图_|木子李|的博客-CSDN博客
menudata结构如下
menudata: [
{
name: "1213",
id: 1,
},
{
name: "12312",
id: 2,
}
]
相关方法如下
onMenuClick(name) {
console.log(name);
},
dragStart(ev) {
this.$bus.$emit("dragStart", ev);
},
dragEnd(event) {
this.$bus.$emit("dragEnd", event);
},
ondrag(e) {
this.$bus.$emit("ondrag", e);
},
transferData(event) {
const name = event.target.innerText;
console.log("++++++++++");
console.log(name);
pubsub.publish("name", name);
},
},
我这里用到了pubsub.js,相关内容小伙伴可以自行百度
然后树组件和树组件对应的拖拽都完成了,该进行拖拽区域的设置了
用到了事件总线总归是有些麻烦的
methods: {
//删除模块
deleteTag(event) {
//将this赋值给thar,这里涉及到this指向问题,所以这里会将this赋值给thar。在需要this的时候,使用thar进行代替。避免了出现函数,变量找不到问题
var thar = this;
var id = event.currentTarget.parentElement.parentElement.parentElement.id;
var ids = id.split("-");
// jsPlumb.remove(id); //移除节点
var deleteID = document.getElementById(id);
var r = confirm('确定将"' + uncompileStr(ids[0]) + '"模块删除?');
if (r == true) {
//点击删除dom
deleteID.addEventListener("click", function () {
thar.plumbIns.deleteConnectionsForElement(deleteID.id);
thar.plumbIns.removeAllEndpoints(deleteID.id); //删除divID所有端点
thar.plumbIns.remove(deleteID.id); //移除节点
});
}
},
//拖拽事件
dragStart(ev) {
console.log("dragstart拖拽开始事件,绑定于被拖拽元素上", ev);
let info = { id: ev.target.id, isDrop: true };
ev.dataTransfer.setData("Text", JSON.stringify(info));
// 鼠标相对于被选中元素的位置
this.offsetX = ev.offsetX;
this.offsetY = ev.offsetY;
//获取标签文本
this.dragName = ev.target.innerText;
},
dragEnd(event) {
event.dataTransfer.clearData();
},
drop(e) {
let info = JSON.parse(e.dataTransfer.getData("Text"));
if (info.isDrop) {
info.x = e.clientX - this.offsetX -300 ;
info.y = e.clientY - this.offsetY -10 ;
// 将加密后的字符串作为 id值
info.id = compileStr(this.dragName) + "-" + Math.random();
//拼接图片地址
info.avatar = require("../../assets/images/dragModule/" +
this.dragName +
".png");
info.name = this.dragName;
this.InfoList.push(info);
//为 div绑定节点
this.$nextTick(() => {
this.addOneAnchor(info.id);
});
}
},
//双击模块,通知popup组件加载对应的组件
doubleClick(id) {
this.identification = id;
this.showAlertModal = true;
this.idarr = id.split("-");
this.componentName = uncompileStr(this.idarr[0]);
},
enterInto(event) {
/// currentTarget 获取绑定点击事件的节点 firstElementChild获取绑定事件节点的第一个子节点
let labelNodeText =
event.currentTarget.firstElementChild.firstElementChild.innerText;
//发布消息
pubsub.publish("name", labelNodeText);
},
},
mounted() {
this.plumbIns = this.$jsPlumb.getInstance();
//将this赋值给thar
var thar = this;
//出口节点
this.plumbIns.addEndpoint(
"exportation",
{ anchor: [0, 0.1] },
exportationStyle
);
this.$nextTick(() => {
/*info.sourceId: 连接的源元素id
info.targetId: 连接的目标元素id
info.source: 连接的源元素
info.target: 连接的目标元素
info.sourceEndpoint: 连接的源端点
info.targetEndpoint: 连接的目标端点*/
thar.plumbIns.ready(() => {
//点击删除连接线
thar.plumbIns.bind("click", function (info) {
thar.plumbIns.deleteConnection(info);
});
});
//当链接建立前 检查是否已经建立连接
thar.plumbIns.bind("beforeDrop", function (info) {
let targetIdArray = thar.dataCache.get(info.sourceId);
//避免源点与目标点在用一处上
//短路运算符&&和||
if (
info.sourceId === info.targetId ||
(Array.isArray(targetIdArray) &&
targetIdArray.indexOf(info.targetId) > -1) ||
targetIdArray === info.targetId
) {
return false; // 链接不会建立
} else {
return true; // 链接会自动建立
}
});
//连接事件
thar.plumbIns.bind("connection", function (info) {
//判断是否与exportation节点建立连接
if (info.targetId == "exportation") {
exportation = true;
}
//将源元素与目标元素id存入到数组中
let array = [info.sourceId, info.targetId];
//调用store中的ad方法,进行添加操作
thar.$store.dispatch("ad", array);
//获取state中的数据
thar.dataCache = thar.$store.state.dataCache;
});
//断开连接
thar.plumbIns.bind("connectionDetached", function (info) {
//断开连接时,将exportation的值修改为false
if (info.targetId == "exportation") {
exportation = false;
}
//将源元素id与目标元素id存入到数组中
let array = [info.sourceId, info.targetId];
//调用storte中dd方法,进行删除操作
thar.$store.dispatch("dd", array);
});
});
//为每一个模块添加对应的节点。
this.addOneAnchor = function (idStr) {
var ids = idStr.split("-");
var decode = uncompileStr(ids[0]);
//添加端点
var getFirstChildId = document.getElementById("region_id").children[0].id;
if (getFirstChildId == idStr) {
/*addEndpoint(参数1,参数2,参数3)
参数1:所需要添加节点元素的id值
参数2:节点位置,jsPlumb有九个默认锚点位置(Top、Right、Bottom、Left、Center...)。数组的语法[x,y]x-相对该锚点在x轴坐标比例(最大1)y-相对该锚点y轴坐标比例(最大1)
参数3:节点样式
*/
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.3] },
rightAnchorStyle
);
//判断 值是否存在数组中
} else if (leftTwo.includes(decode)) {
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.4] }, leftAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.6] }, leftAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: "Right" }, rightAnchorStyle);
} else if (rightghtTwo.includes(decode)) {
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.4] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.6] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(idStr, { anchor: "Left" }, leftAnchorStyle);
} else if (leftTwo_rightThree.includes(decode)) {
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.4] }, leftAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.6] }, leftAnchorStyle);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.3] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.5] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.7] },
rightAnchorStyle
);
} else if (leftTwo_rightTwo.includes(decode)) {
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.4] }, leftAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.6] }, leftAnchorStyle);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.4] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.6] },
rightAnchorStyle
);
} else if (rightThree.includes(decode)) {
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.3] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.5] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.7] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.5] }, leftAnchorStyle);
} else if (rightOne.includes(decode)) {
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.5] },
rightAnchorStyle
);
} else if (leftOne.includes(decode)) {
this.plumbIns.addEndpoint(idStr, { anchor: [0, 0.5] }, leftAnchorStyle);
} else if (classify.includes(decode)) {
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.3] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.5] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.7] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(
idStr,
{ anchor: [1, 0.9] },
rightAnchorStyle
);
this.plumbIns.addEndpoint(idStr, { anchor: "Right" }, rightAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: "Left" }, leftAnchorStyle);
} else {
this.plumbIns.addEndpoint(idStr, { anchor: "Right" }, rightAnchorStyle);
this.plumbIns.addEndpoint(idStr, { anchor: "Left" }, leftAnchorStyle);
}
//设置可移动区域
this.plumbIns.draggable(idStr, { containment: this.regionId });
};
//消息订阅
this.closeMoreNodeDescribe = pubsub.subscribe(
"closeMoreNodeDescribe",
(msgName, data) => {
this.moreNodeDescribe = data;
}
);
//消息订阅
this.pid = pubsub.subscribe("showAlertModal", (msgName, data) => {
this.showAlertModal = data;
});
//全局总线
this.$bus.$on("dragStart", this.dragStart);
this.$bus.$on("dragEnd", this.dragEnd);
//this.$bus.$on("ondrag", this.ondrag);
},
就这样吧,拍拍手,下播