This article example shares the specific code of Vue using drag and drop to create a structure tree for your reference. The specific content is as follows Drag the nodes in the dotted box on the page to create a right-facing structure tree, as shown below. Record implementation ideas: vueTree.vue <template> <div class="container"> <div class="node-container"> <div v-for="(item, index) in nodeList" :key="index" class="source-node" draggable="true" @dragstart="dragStart(item)"> {{ item }} </div> </div> <div class="tree-container" @dragover="allowDrop" @drop="handleDrop"> <tree-node v-if="nodeData" ref="node" :nodeData="nodeData" @delete-node="deleteTree" /> </div> </div> </template> <script> import TreeNode from './treeNode.vue' import { Node } from './config.js' export default { name: 'vue-tree', components: TreeNode }, // Descendant nodes cannot obtain node data, that is, they cannot create nodes independently, so the node creation method of the ancestor node is exposed to the descendant nodes provide () { return { createNode: this.createNode } }, data () { return { nodeList: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], currNode: null, nodeData: null } }, methods: { // Start dragging and get node data dragStart (item) { this.currNode = item }, // If the root node is not generated, dragging is allowedallowDrop (event) { if (!this.nodeData) { event.preventDefault() } }, //Drag ends, generate node handleDrop () { if (!this.nodeData) { this.nodeData = this.createNode() } }, createNode () { let node = new Node(this.currNode) return node }, // Delete the root node and delete the entire tree deleteTree () { this.nodeData = null } } } </script> <style lang="scss" scoped> .container { padding: 20px; width: calc(100% - 40px); height: calc(100% - 40px); .node-container { height: 100px; border: 1px dashed red; display: flex; .source-node { width: 50px; height: 30px; background: #fff; border: 1px solid blue; text-align: center; line-height: 30px; margin: 10px; cursor: pointer; } } .tree-container { height: calc(100% - 122px); margin-top: 20px; } } </style> config,js export class Node{ constructor(name){ this.name = name, this.children = [] } } treeNode.vue <template> <!-- Structure: The outermost layer is node-inner. Each node-inner contains a node and a node-box. The node stores the current node, and the node-box stores all the child nodes of the current node. If the current node has several child nodes, there will be several node-ins in the node-box, and so on. <node></node> <node-box> <node-inner> <node></node> <node-box>...</node-box> </node-inner> <node-inner> <node></node> <node-box>...</node-box> </node-inner> ... </node-box> </node-inner> --> <div class="node-inner"> <div class="node" :class="{ 'drag-over-node': isDragover }" @dragover="dragOver" @dragleave="dragLeave" @drop="nodeDrop"> <span class="name">{{nodeData.name}}</span> <span class="del" @click="deleteNode">Delete</span> </div> <div v-show="nodeData.children.length > 0" class="node-box"> <tree-node v-for="(item,index) in nodeData.children" :key="index" :nodeData="item" @delete-node="deleteChild(index)" /> </div> </div> </template> <script> export default { name: 'tree-node', props: { nodeData: { type: Object, default: () => { } } }, // Get the data passed by the ancestor node inject: ['createNode'], data () { return { isDragover: false } }, methods: { // The node allows dragging to add child nodes dragOver (event) { event.preventDefault() if (!this.isDragover) { this.isDragover = true } }, dragLeave() { if (this.isDragover) { this.isDragover = false } }, // Add child nodes to the node nodeDrop () { let node = this.createNode() this.nodeData.children.push(node) this.isDragover = false }, // Delete the current node, which essentially means handing it over to the parent to delete the child node deleteNode () { this.$emit("delete-node") }, // Receive the instruction to delete the child node and execute the delete function deleteChild (index) { this.nodeData.children.splice(index, 1) } } } </script> <style lang="scss" scoped> .node { border: 1px solid orange; border-radius: 4px; position: relative; display: inline-flex; align-items: center; justify-content: space-between; background-color: #fff; height: 36px; padding: 0 12px 0 16px; line-height: 36px; margin-bottom: 10px; .name { font-size: 16px; margin-right: 12px; } .del { color: red; font-size: 12px; cursor: pointer; } &.drag-over-node { box-shadow: 6px 6px 12px rgba(106, 20, 134, 0.15); } } .node-box { display: inline-flex; flex-direction: column; .node-inner { margin-left: 80px; // Connect the vertical bars&:not(:last-child):before { position: absolute; left: -70px; top: 22px; border: 1px solid orange; content: ""; width: 8px; background-color: #fff; border-bottom-color: #fff; height: 100%; border-top-color: #fff; z-index: 3; } // Connect horizontal bar&:after { left: -61px; width: 60px; content: ""; position: absolute; top: 14px; height: 8px; border: 1px solid orange; content: ""; background-color: #fff; border-right-color: #fff; border-left-color: #fff; z-index: 3; } // The last vertical bar has a rounded corner &:nth-last-child(2):before { border-bottom-left-radius: 6px; border-bottom-color: orange; } // The first horizontal bar is extended &:first-child:after { left: -81px; width: 80px; z-index: 2; } } } .node-inner { position: relative; } </style> The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: Two ways to exit bash in docker container under Linux
>>: Analysis of the locking mechanism of MySQL database
This article shares the specific code of jQuery t...
Preface Today, Prince will talk to you about the ...
1. Check the character set of the default install...
Preface The effect problems used in personal actu...
Table of contents Preface 1. Basic knowledge of d...
This article mainly introduces the breadcrumb fun...
Starting from this section, we will explain the i...
Edit docker-compose.yml and add the following con...
Operating environment: MAC Docker version: Docker...
This article example shares the specific code of ...
Here 123WORDPRESS.COM presents the first part of ...
1. CSS realizes fixed width on the left and adapt...
In the article MySQL Optimization: Cache Optimiza...
1. Commonjs Commonjs is a custom module in nodejs...
CSS media query has a very convenient aspect rati...