關(guān)于使用vue3 +element-plus+ts 寫(xiě)了2個(gè)el-tree組件的拖拽添加節(jié)點(diǎn)

需了解的知識(shí)html 原生拖拽事件

HTML 拖放 API - Web API 接口參考 | MDN (mozilla.org)

沒(méi)有使用el-plus tree中的自身拖拽 因?yàn)椴环衔业男枨? 而且用了自帶的實(shí)現(xiàn)不了2個(gè)tree拖拽放置

效果展示

原始數(shù)據(jù)憔披,下面的tree是out樹(shù),上面的是in樹(shù)


原始數(shù)據(jù).PNG

鼠標(biāo)選中下面節(jié)點(diǎn)(! 只有選中節(jié)點(diǎn)文字時(shí),才能拖拽戚长,不過(guò)后期可以修改)见间,可拖拽成為上面tree的子節(jié)點(diǎn)


拖拽中.PNG

鼠標(biāo)hover
節(jié)點(diǎn)可以 添加子節(jié)點(diǎn)或者刪除當(dāng)前節(jié)點(diǎn)攒砖,添加時(shí)作郭,自動(dòng)變成輸入框鲸匿,可以修改名稱(chēng),輸入框失焦時(shí)镊绪,可保存名字


添加刪除節(jié)點(diǎn).PNG

代碼展示 可以借鑒哦(馬馬虎虎啦)

<template>


  <div style='width:400px;user-select: none;'>
    <el-tree :data="dataSource" node-key="id" default-expand-all :expand-on-click-node="false" ref='treeIn'
      @node-click='clickTree'>
      <template #default="{ node, data }">

        <el-input v-model='data.label' size="small" v-if='data.edit' @blur='data.edit = false'></el-input>
        <span :id='data.id' @drop="drop_handler" @dragover="dragover_handler" v-else @dblclick='data.edit=true'>{{
          node.label }}</span>


        <span style='margin-left: 20px;' class='tree-btn'>
          <el-button @click="append(data)" size="small" text type="success" v-if="data.flag!=='entity'"> add
          </el-button>
          <el-button @click="remove(node, data)" size="small" text type="success">del
          </el-button>
        </span>
      </template>
    </el-tree>


    <div style='border:1px solid red;margin-top: 30px;'>
      <el-tree :data="dataSource2" node-key="id" default-expand-all :expand-on-click-node="false" ref='treeOut'>
        <template #default="{ node, data }">

          <span :id='data.id' draggable="true" @dragstart="handleNodeDragStart">{{ node.label }}</span>

        </template>
      </el-tree>
    </div>
  </div>

</template>

<script setup lang='ts'>
  import {reactive,onMounted,ref} from 'vue'
  import {ElTree} from 'element-plus'
  import type Node from 'element-plus/es/components/tree/src/model/node'

  interface Tree {
    id: number
    label: string
    children?: Tree[],
    flag?: 'entity'
  }

  const treeIn=ref<InstanceType<typeof ElTree>>()
  const treeOut=ref<InstanceType<typeof ElTree>>()


  const dataSource=ref<Tree[]>([
    {
      id: 1,
      label: '蔬菜',
      edit: false,
      children: [
        {
          id: 4,
          label: '紅色的',
          children: [
            {
              id: 9,
              edit: false,
              label: '辣椒',
            },
            {
              edit: false,
              id: 10,
              label: '丸子',
            },
          ],
        },
      ],
    },
    {
      id: 2,
      label: '水果',
      edit: false,
      children: [
        {
          id: 5,
          edit: false,
          label: '軟乎乎的',
        },
        {
          id: 6,
          edit: false,
          label: '刺刺的',
        },
      ],
    },
    {
      id: 3,
      label: '雜類(lèi)',
      edit: false,
      children: [
        {
          id: 7,
          label: '紅綠色',
          edit: false,
        },
        {
          id: 8,
          edit: false,
          label: '黑紫色',
        },
      ],
    },
  ])

  const handleNodeDragStart=(ev) => {
    ev.dataTransfer.dropEffect="copy";
    ev.dataTransfer.setData("text/plain",ev.target.id);
  }



  function dragover_handler(ev) {
    ev.preventDefault();
    ev.dataTransfer.dropEffect="link";
  }

  function drop_handler(ev) {
    ev.preventDefault();

    let outId=ev.dataTransfer.getData("text/plain");
    let inId=ev.target.id

    // 獲取拖拽節(jié)點(diǎn)
    let outNode=treeOut.value.getNode(Number(outId))
    treeIn.value.append(outNode.data,Number(inId))
    // ev.target.appendChild(document.getElementById(data));
  }

  const dataSource2=ref<Tree[]>([
    {
      id: 1,
      label: '食品列表',
      children: [
        {
          id: 4,
          label: '香蕉',
          children: [],
          flag: 'entity'
        },
        {
          id: 5,
          label: '菠蘿',
          children: [],
          flag: 'entity'
        },

        {
          id: 43,
          label: '榴蓮(哈哈 我的最?lèi)?ài))',
          children: [],
          flag: 'entity'
        },
        {
          id: 44,
          label: '西紅柿雞蛋(不喜歡)',
          children: [],
          flag: 'entity'
        },
        {
          id: 45,
          label: '茄子',
          children: [],
          flag: 'entity'
        },
        {
          id: 46,
          label: '香菇',
          children: [],
          flag: 'entity'
        },


      ],
    },
  ])

  let id=1000

  const append=(data: Tree) => {
    const newChild={id: id++,label: '新增節(jié)點(diǎn)',children: [],edit: true}
    if(!data.children) {
      data.children=[]
    }
    data.children.push(newChild)
    dataSource.value=[...dataSource.value]
  }
  const remove=(node: Node,data: Tree) => {
    const parent=node.parent
    const children: Tree[]=parent.data.children||parent.data
    const index=children.findIndex((d) => d.id===data.id)
    children.splice(index,1)
    dataSource.value=[...dataSource.value]
  }

  const clickTree=(data: Tree,node: Node) => {
    console.log(node)
  }
  onMounted(() => {


  })
</script>

<style scoped lang="scss">
  .el-tree-node__content {
    .tree-btn {
      display: none;
    }
  }

  .el-tree-node__content:hover {
    .tree-btn {
      display: block;
    }
  }
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末匀伏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蝴韭,更是在濱河造成了極大的恐慌够颠,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榄鉴,死亡現(xiàn)場(chǎng)離奇詭異履磨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)庆尘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)剃诅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人驶忌,你說(shuō)我怎么就攤上這事矛辕。” “怎么了付魔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵聊品,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我几苍,道長(zhǎng)翻屈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任妻坝,我火速辦了婚禮妖胀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惠勒。我一直安慰自己赚抡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布纠屋。 她就那樣靜靜地躺著涂臣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪售担。 梳的紋絲不亂的頭發(fā)上赁遗,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音族铆,去河邊找鬼岩四。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哥攘,可吹牛的內(nèi)容都是我干的剖煌。 我是一名探鬼主播材鹦,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耕姊!你這毒婦竟也來(lái)了桶唐?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茉兰,失蹤者是張志新(化名)和其女友劉穎尤泽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體规脸,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坯约,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了莫鸭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鬼店。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖黔龟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情滥玷,我是刑警寧澤氏身,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站惑畴,受9級(jí)特大地震影響蛋欣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜如贷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一陷虎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杠袱,春花似錦尚猿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至纹蝴,卻和暖如春庄萎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背塘安。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工糠涛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兼犯。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓忍捡,卻偏偏與公主長(zhǎng)得像集漾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锉罐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容