Vue implements a draggable tree structure diagram

Vue implements a draggable tree structure diagram

I recently used Vue to make a small project - a draggable tree structure diagram.

Vue recursive component

The structure is implemented through Vue's recursive components

The layout uses flex, and the structural lines are implemented by CSS pseudo-classes

It should be noted that for centered layout, when there are too many elements on the X-axis and the width of the child elements exceeds the view, although there is a scroll bar after the element is centered, it can only reach the content on the right, and the content on the left will be inaccessible. You can set the parent element to inline-flex and the width to auto. Of course, if it is the above structure, there will be no such problem, but when it comes to big data rendering, it still bothered me for an afternoon.

drag event

First, bind the draggable attribute to the element you want to drag. Except for the <a> and <img> tags, which are set to true by default, all other elements need to be set as follows

Then there are three events: dragend , dragover , and drop (written in Vue, so don’t add on before the event)

Note that dragover needs to remove the default behavior and give $event.preventDefault() in the event. Otherwise, the mouse will have a 🚫 sign when dragging, making the dragging invalid.

To transfer the value of the dragged element to the dropped location, you need to use $event.dataTransfer.setData("node", transNodeData)

"node" is equivalent to the variable name of the data to be passed, and needs to be JSON.stringify()

methods:{
    dragstart(e,nodeObj){
      console.log('🐉drag moving point',nodeObj.name,);
      let transData = JSON.stringify(nodeObj) //The data passed by dragging is first converted to JSON format e.dataTransfer.setData("node", transData)
    },
    dragover(e){
      e.preventDefault()
    },
    drop(e,nodeObj){
      console.log('🐉dropped to',nodeObj.name);
      let getData = JSON.parse( e.dataTransfer.getData("node"))
      console.log('Get data',getData);
    }
  }

Knowing this, the next thing to do is to put the acquired drag point data into the children array of the placement point, and delete the drag point from the children array of the parent node in dragend event. The index of the node is obtained when dragstart event is triggered and passed to dragend through eventBus component communication method ( Vuex can also be used).

Create a bus folder and create a new index.js file

import Vue from "vue"
const busEvent = new Vue({
  data(){
    return {
      dragNodeIndex:-1, //The index of the drag node in the parent node children array
    }
  },
  created(){
    this.$on("transDragNodeIndex", res=>{//To monitor $emit through $on, you need to ensure that the custom event is monitored before it is triggered, that is, subscription precedes publishing, otherwise the data cannot be monitored. I have not used eventBus much, so this is a pit this.dragNodeIndex=res
    })
  }
})

export default busEvent

Introduce eventBus in the component. After triggering the custom event through $emit in dragstart , $on can receive this data. In dragend , you can get this index through eventBus and then delete it from the array.

The next step is to make some logical judgments. For example, if a parent node cannot be dragged to a child node, first recursively traverse the names of all child nodes on the parent node into an array. If name of the drop position is in the array, it means that the parent is dropped to the child, and the state is set to true.

ifFatherDragToSon(dragObj,dropObj){//Judge whether the parent node has moved to the child nodeif (dragObj.children.length === 0) return false;
      let newArr = [];
      function getAllName(dragObj) {
        newArr.push(...dragObj.children);
        if (dragObj.children.length === 0) {
          return;
        } else {
          for (let i = 0; i < dragObj.children.length; i++) {
            getAllName(dragObj.children[i]);
          }
        }
      }
      getAllName(dragObj);
      if (newArr.includes(dropObj)) {
        return true;
      }
      return false;
    }

Use eventBus to get the status of dragend event, and return directly if it is true

Dragging to itself doesn't work either, just return directly. A child node is added under the "Li Hu Chong" point, mainly to verify that the address of the node in the stack is used for judgment, rather than based on name attribute.

Another thing to mention is $event.dataTransfer.dropEffect in the drag event. The values ​​that can be obtained are move , copy , none , link . In the figure below, when dropEffect is 🚫, the drag point disappears. In fact, the code in dragend event is executed, while the code in the drop event is not executed, so this step requires process control first. In addition, the default dropEffect of different browsers is also different, such as 360 browser.

Code connection

The above is the detailed content of Vue's implementation of a draggable tree structure diagram. For more information about Vue's implementation of a tree structure diagram, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Vue suspended draggable floating button example code
  • vue draggable resizable realizes the component function of draggable scaling
  • Vue implements the draggable function of element-ui dialog box
  • Vue uses echarts to draw an organizational chart
  • How to implement Vue custom tree structure diagram

<<:  Mysql 5.7.19 free installation version encountered pitfalls (collection)

>>:  How to implement email alert in zabbix

Recommend

An article to help you understand Js inheritance and prototype chain

Table of contents Inheritance and prototype chain...

Detailed tutorial on running selenium+chromedriver on the server

1. Introduction I want to use selenium to scrape ...

Use of Linux watch command

1. Command Introduction The watch command execute...

How to use filters to implement monitoring in Zabbix

Recently, when I was working on monitoring equipm...

Detailed steps for configuring Tomcat server in IDEA 2020

The steps for configuring Tomcat in IDEA 2020 are...

10 content-related principles to improve website performance

<br />English address: http://developer.yaho...

MySQL data insertion efficiency comparison

When inserting data, I found that I had never con...

Docker-compose one-click deployment of gitlab Chinese version method steps

1. Introduction to gitlab Gitlab official address...

JavaScript to implement login form

This article example shares the specific code of ...

A brief analysis of CSS3 using text-overflow to solve text layout problems

Basic syntax The use of text-overflow requires th...

Regarding the Chinese garbled characters in a href parameter transfer

When href is needed to pass parameters, and the p...