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
Comprehensive Documentation github address https:...
The virtual machine I rented from a certain site ...
1. Open the CentOS 7 virtual machine. 2. Log in t...
To beautify the table, you can set different bord...
Preface When using Docker in a production environ...
The first cutter in China github.com/chokcoco Fir...
When you first start using Docker, you will inevi...
How to write DROP TABLE in different databases 1....
This article shares the download and installation...
Table of contents Boolean Type Number Types Strin...
Preview knowledge points. Animation Frames Backgr...
Copy code The code is as follows: <!--[if !IE]...
How to reset the initial value of the auto-increm...
This article example shares the specific code of ...
1. Download the alpine image [root@DockerBrian ~]...