您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

vue使用拖拽方式创建结构树

51自学网 2022-02-21 13:40:03
  javascript

本文实例为大家分享了vue使用拖拽方式创建结构树的具体代码,供大家参考,具体内容如下

在页面中拖拽虚线框中的节点,创建向右的结构树,如下图

记录实现思路:

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  },  // 后代节点无法获取节点数据,即无法独立创建节点,所以将祖先节点的创建节点方法暴露给后代节点  provide () {    return {      createNode: this.createNode    }  },  data () {    return {      nodeList: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],      currNode: null,      nodeData: null    }  },  methods: {    // 开始拖拽,获取节点数据    dragStart (item) {      this.currNode = item    },    // 若未生成跟节点,则允许拖拽    allowDrop (event) {      if (!this.nodeData) {        event.preventDefault()      }    },    // 拖拽结束,生成节点    handleDrop () {      if (!this.nodeData) {        this.nodeData = this.createNode()      }    },    createNode () {      let node = new Node(this.currNode)      return node    },    // 根节点删除,删除整个树    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>  <!--     结构:最外层是node-inner,每个node-inner中有一个node与node-box,node存放当前节点,node-box存放当前节点的全部子节点,当前节点有几个子节点则node-box中就会有几个node-inner,以此循环      <node-inner>        <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">删除</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: () => { }    }  },  // 获取祖先节点传递的数据  inject: ['createNode'],  data () {    return {      isDragover: false    }  },  methods: {    // 节点允许拖拽添加子节点    dragOver (event) {      event.preventDefault()      if (!this.isDragover) {        this.isDragover = true      }    },    dragLeave () {      if (this.isDragover) {        this.isDragover = false      }    },    // 为节点添加子节点    nodeDrop () {      let node = this.createNode()      this.nodeData.children.push(node)      this.isDragover = false    },    // 删除当前节点,本质是交给父级删除子节点    deleteNode () {      this.$emit("delete-node")    },    // 接收删除子节点的指令并执行删除功能    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;    // 连接竖条    &: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;    }    // 连接横条    &: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;    }    // 最后一个竖条圆滑拐角    &:nth-last-child(2):before {      border-bottom-left-radius: 6px;      border-bottom-color: orange;    }    // 第一个横条拉长    &:first-child:after {      left: -81px;      width: 80px;      z-index: 2;    }  }}.node-inner {  position: relative;}</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持51zixue.net。


下载地址:
JavaScript web表单功能交流干货满满
vue中的ElementUI的使用详解
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。