vue实现树状结构+拖拽

1.首先说树状结构的实现
我直接推一手链接,直接用他的最终源码就可以
HTML&CSS中的树形结构图_html树状结构图_|木子李|的博客-CSDN博客

然后,我这里有一些改动
vue实现树状结构+拖拽_第1张图片

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);
  },

就这样吧,拍拍手,下播

你可能感兴趣的:(vue,vue.js,前端,javascript)