最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue使用拖拽方式創(chuàng)建結(jié)構(gòu)樹

 更新時(shí)間:2021年10月12日 10:03:48   作者:javscp_q  
這篇文章主要為大家詳細(xì)介紹了vue使用拖拽方式創(chuàng)建結(jié)構(gòu)樹,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue使用拖拽方式創(chuàng)建結(jié)構(gòu)樹的具體代碼,供大家參考,具體內(nèi)容如下

在頁(yè)面中拖拽虛線框中的節(jié)點(diǎn),創(chuàng)建向右的結(jié)構(gòu)樹,如下圖

記錄實(shí)現(xiàn)思路:

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
  },
  // 后代節(jié)點(diǎn)無(wú)法獲取節(jié)點(diǎn)數(shù)據(jù),即無(wú)法獨(dú)立創(chuàng)建節(jié)點(diǎn),所以將祖先節(jié)點(diǎn)的創(chuàng)建節(jié)點(diǎn)方法暴露給后代節(jié)點(diǎn)
  provide () {
    return {
      createNode: this.createNode
    }
  },
  data () {
    return {
      nodeList: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
      currNode: null,
      nodeData: null
    }
  },
  methods: {
    // 開始拖拽,獲取節(jié)點(diǎn)數(shù)據(jù)
    dragStart (item) {
      this.currNode = item
    },
    // 若未生成跟節(jié)點(diǎn),則允許拖拽
    allowDrop (event) {
      if (!this.nodeData) {
        event.preventDefault()
      }
    },
    // 拖拽結(jié)束,生成節(jié)點(diǎn)
    handleDrop () {
      if (!this.nodeData) {
        this.nodeData = this.createNode()
      }
    },
    createNode () {
      let node = new Node(this.currNode)
      return node
    },
    // 根節(jié)點(diǎn)刪除,刪除整個(gè)樹
    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>
  <!-- 
    結(jié)構(gòu):最外層是node-inner,每個(gè)node-inner中有一個(gè)node與node-box,node存放當(dāng)前節(jié)點(diǎn),node-box存放當(dāng)前節(jié)點(diǎn)的全部子節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)有幾個(gè)子節(jié)點(diǎn)則node-box中就會(huì)有幾個(gè)node-inner,以此循環(huán)
      <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: () => { }
    }
  },
  // 獲取祖先節(jié)點(diǎn)傳遞的數(shù)據(jù)
  inject: ['createNode'],
  data () {
    return {
      isDragover: false
    }
  },
  methods: {
    // 節(jié)點(diǎn)允許拖拽添加子節(jié)點(diǎn)
    dragOver (event) {
      event.preventDefault()
      if (!this.isDragover) {
        this.isDragover = true
      }
    },
    dragLeave () {
      if (this.isDragover) {
        this.isDragover = false
      }
    },
    // 為節(jié)點(diǎn)添加子節(jié)點(diǎn)
    nodeDrop () {
      let node = this.createNode()
      this.nodeData.children.push(node)
      this.isDragover = false
    },
    // 刪除當(dāng)前節(jié)點(diǎn),本質(zhì)是交給父級(jí)刪除子節(jié)點(diǎn)
    deleteNode () {
      this.$emit("delete-node")
    },
    // 接收刪除子節(jié)點(diǎn)的指令并執(zhí)行刪除功能
    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;
    }
    // 最后一個(gè)豎條圓滑拐角
    &:nth-last-child(2):before {
      border-bottom-left-radius: 6px;
      border-bottom-color: orange;
    }
    // 第一個(gè)橫條拉長(zhǎng)
    &:first-child:after {
      left: -81px;
      width: 80px;
      z-index: 2;
    }
  }
}
.node-inner {
  position: relative;
}
</style>

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue動(dòng)態(tài)添加class可能帶來(lái)的問(wèn)題解讀(被覆蓋)

    Vue動(dòng)態(tài)添加class可能帶來(lái)的問(wèn)題解讀(被覆蓋)

    文章討論了在使用Vue.js時(shí),通過(guò)動(dòng)態(tài)class修改元素樣式時(shí)可能會(huì)遇到的問(wèn)題,當(dāng)通過(guò)JavaScript動(dòng)態(tài)添加類時(shí),Vue的動(dòng)態(tài)class會(huì)覆蓋掉通過(guò)JavaScript添加的類,導(dǎo)致樣式丟失,這個(gè)問(wèn)題在實(shí)際開發(fā)中可能會(huì)遇到,尤其是在使用第三方框架
    2024-12-12
  • vue2組件進(jìn)階與插槽詳解(推薦!)

    vue2組件進(jìn)階與插槽詳解(推薦!)

    插槽(slot)作用是讓父組件可以往子組件指定位置插入?html?結(jié)構(gòu),也是組件的一種通信方式,下面這篇文章主要給大家介紹了關(guān)于vue2組件進(jìn)階與插槽的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 一次在vue中使用post進(jìn)行excel表下載的實(shí)戰(zhàn)記錄

    一次在vue中使用post進(jìn)行excel表下載的實(shí)戰(zhàn)記錄

    最近遇到了需求,覺著有必要給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于一次在vue中使用post進(jìn)行excel表下載的實(shí)戰(zhàn)記錄,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Vue自定義指令詳解

    Vue自定義指令詳解

    這篇文章主要為大家介紹了Vue自定義指令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • Vue3+ElementPlus el-date-picker設(shè)置可選時(shí)間范圍的示例代碼

    Vue3+ElementPlus el-date-picker設(shè)置可選時(shí)間范圍的示例代碼

    在Vue3中使用Element Plus的el-date-picker組件設(shè)置可選時(shí)間范圍,你可以使用disabled-date屬性,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-07-07
  • vue實(shí)現(xiàn)消息向上無(wú)縫滾動(dòng)效果

    vue實(shí)現(xiàn)消息向上無(wú)縫滾動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)消息向上無(wú)縫滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue?實(shí)現(xiàn)彈窗關(guān)閉后刷新效果

    vue?實(shí)現(xiàn)彈窗關(guān)閉后刷新效果

    這篇文章主要介紹了vue?實(shí)現(xiàn)彈窗關(guān)閉后刷新效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue-resource攔截器設(shè)置頭信息的實(shí)例

    vue-resource攔截器設(shè)置頭信息的實(shí)例

    下面小編就為大家?guī)?lái)一篇vue-resource攔截器設(shè)置頭信息的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • 詳解vue-cli 腳手架項(xiàng)目-package.json

    詳解vue-cli 腳手架項(xiàng)目-package.json

    本篇文章主要介紹了詳解vue-cli 腳手架項(xiàng)目-package.json,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Vue中mixins的使用方法詳解

    Vue中mixins的使用方法詳解

    mixins是一種分發(fā) Vue 組件中可復(fù)用功能的使用方式,它是一個(gè) js 對(duì)象,包含我們組件script中的任意功能選項(xiàng),下面就跟隨小編一起來(lái)看看它的具體使用吧
    2024-03-03

最新評(píng)論

博客| 乐昌市| 济源市| 安阳县| 沁水县| 浦北县| 瓦房店市| 宝坻区| 华阴市| 增城市| 汽车| 西华县| 赤水市| 温泉县| 慈利县| 新源县| 安泽县| 全椒县| 毕节市| 永宁县| 太和县| 明光市| 临湘市| 洞口县| 南澳县| 双峰县| 天全县| 伊通| 观塘区| 松溪县| 衡山县| 龙门县| 合江县| 延安市| 华蓥市| 长寿区| 洱源县| 阜康市| 陆丰市| 余姚市| 五大连池市|