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

Vue implements 3 ways to switch tabs and switch to maintain data status

3 ways to implement tab switching in Vue 1. v-sho...

MySQL 5.7 installation and configuration tutorial

This article shares the MySQL installation and co...

MySQL query sorting and paging related

Overview It is usually not what we want to presen...

Zabbix configures DingTalk's alarm function with pictures

Implementation ideas: First of all, the alarm inf...

Steps to set up Windows Server 2016 AD server (picture and text)

Introduction: AD is the abbreviation of Active Di...

Complete step record of Vue encapsulation of general table components

Table of contents Preface Why do we need to encap...

How to use the debouce anti-shake function in Vue

Table of contents 1. Anti-shake function 2. Use d...

A brief analysis of the use of watchEffect in Vue3

Preface Everyone should be familiar with the watc...

Sample code for modifying the input prompt text style in html

On many websites, we have seen the input box disp...

Solution to Docker's failure to release ports

Today I encountered a very strange situation. Aft...

How to install and configure mysql 5.7.19 under centos6.5

The detailed steps for installing mysql5.7.19 on ...

The difference between shtml and html

Shtml and asp are similar. In files named shtml, s...

React uses routing to redirect to the login interface

In the previous article, after configuring the we...