vue 拖拽

1、左右容器拖拽

2、容器内位置拖拽切换

3、判断性拖拽(若不适配,鼠标显示禁止拖拽图标)

4、点击大标题,变输入框修改,最后提交表单

 

<template>
  <div>
    <div class="left_list">
      <div class="_flex">
        <transition-group tag="div">
          <div
            class="item list_wrap"
            :class="'item' + index"
            v-for="(item, index) in dataList"
            :key="index"
            v-if="item.key!='box'"
            @drop='onDrop($event, item.key)'
            @dragover.prevent="dragOver($event, item,index)"
            @dragenter.prevent
          >
            <h2 v-on:dblclick="editTitle(index,true)" v-show="!item.showTitleEdit">{{ item.title }}</h2>
            <Input v-model="item.title" :autofocus="true" :ref="'editInput'+index" v-show="item.showTitleEdit"
                   @on-blur="editTitle(index,false)"/>
            <p v-if="item.children&&item.children.length>0" v-for="(row,_index) in item.children" :key="_index"
               draggable="true"
               @dragstart="handleDragStart($event, item,index,_index)"
               @dragover.prevent="handleDragOver($event, item,index,_index)"
               @dragenter="handleDragEnter($event, item,index,_index)"
               @dragend="handleDragEnd($event, item,index,_index)">
              {{ row.lable }}
              <Icon @click="deleteItem(index,_index)" type="md-close-circle"/>
            </p>

          </div>
        </transition-group>
      </div>
      <div class="_flex">
        <transition-group tag="div">
          <div
            class="item list_wrap"
            :class="'item' + index"
            v-for="(item, index) in dataList"
            :key="index"
            v-if="item.key=='box'"
            @drop='onDrop($event, item.key)'
            @dragover.prevent="dragOver($event, item,index)"
            @dragenter.prevent
          >
            <h2 v-on:dblclick="editTitle(index,true)" v-show="!item.showTitleEdit">{{ item.title }}</h2>
            <Input v-model="item.title" :autofocus="true" :ref="'editInput'+index" v-show="item.showTitleEdit"
                   @on-blur="editTitle(index,false)"/>
            <p v-if="item.children&&item.children.length>0" v-for="(row,_index) in item.children" :key="_index"
               draggable="true"
               @dragstart="handleDragStart($event, item,index,_index)"
               @dragenter="handleDragEnter($event, item,index,_index)"
               @dragend="handleDragEnd($event, item,index,_index)">
              {{ row.lable }}
              <Icon @click="deleteItem(index,_index)" type="md-close-circle"/>
            </p>
          </div>
        </transition-group>
      </div>
    </div>
    <div class="right_list">
      <h1>检测限</h1>
      <div class="_list" v-for="(item,index) in rightList" :key="index">
        <h2>{{ item.title }}</h2>
        <p v-if="item.children&&item.children.length>0" v-for="(row,_index) in item.children" :key="_index"
           draggable
           @dragstart='startDrag($event, item,index,_index)'
           @dragend="dragEnd($event, item,index,_index)">{{ row.lable }}</p>
      </div>
    </div>
    <Button @click="getD">按钮</Button>
  </div>
</template>

<script>
export default {
  name: 'test2',
  data () {
    return {
      dataList: [
        {
          title: '电源状态',
          key: 'power',
          showTitleEdit: false,
          children: [{lable: '电压(V)'}, {lable: '总电量'}, {lable: '电流(A)'}, {lable: '电压故障次数'}, {lable: '漏电流(mA)'}, {lable: '电流故障次数'}]
        },
        {
          title: '环境',
          key: 'surroundings',
          showTitleEdit: false,
          children: [{lable: '温度1'}, {lable: '温度2'}, {lable: '湿度'}, {lable: '雷击次数'}]
        },
        {
          title: 'IO输出',
          key: 'IOOutput',
          showTitleEdit: false,
          children: [{lable: '主继电器'}, {lable: '报警'}, {lable: 'LED'}, {lable: '风扇'}, {lable: '频闪灯'}]
        },
        {
          title: '箱体布防状态',
          key: 'box',
          showTitleEdit: false,
          children: [{lable: '空开检测'}, {lable: '压敏监测'}, {lable: '门磁监测'}, {lable: '倾斜监测'}, {lable: '水浸监测'}, {lable: '雷击监测'}]
        }
      ],
      rightList: [
        {
          title: 'IO输入',
          key: 'surroundings',
          children: [{lable: '电压11111'}, {lable: '总电量1111'}, {lable: '电流111(A)'}, {lable: '电压故障次数1111'}, {lable: '漏电流111(mA)'}, {lable: '电流故障次数111'}]
        },
        {
          title: '模拟量',
          key: 'box',
          children: [{lable: '温度133333'}, {lable: '温度233333'}, {lable: '湿度33333'}, {lable: '雷击次数33333'}]
        },
        {
          title: '电压值',
          key: 'power',
          children: [{lable: '主继电器2222'}, {lable: '报警2222'}, {lable: 'LED222'}, {lable: '风扇2222'}, {lable: '频闪灯222'}]
        }
      ],
      ending: null,
      dragging: null,
      newDrag: true,
      parentDragging: null
    }
  },
  methods: {
    // 父拖动
    startDrag (event, item, index, _index) {
      event.dataTransfer.dropEffect = 'move'
      event.dataTransfer.effectAllowed = 'move'
      this.newDrag = true
      this.parentDragging = Object.assign({}, item, {itemIndex: index, rowIndex: _index})
      this.dragging = null
      this.ending = null
    },
    dragOver(event, item, index) {
      // event.dataTransfer.dropEffect = 'move'
      if (this.newDrag) {
        //判断父类移入
        event.dataTransfer.dropEffect = this.parentDragging.key == item.key ? 'move' : 'none'
      }
    },
    dragEnd (event, item, index, _index) {
      this.newDrag = true
    },
    onDrop (event, list) {
      if (list == this.parentDragging.key) {
        for (let item of this.dataList) {
          if (item.key == this.parentDragging.key) {
            item.children.push(this.rightList[this.parentDragging.itemIndex].children[this.parentDragging.itemIndex])
            break
          }
        }
      } else {
        if (this.newDrag) {
          // 不是左边拖动
          this.$Message.error('当前key不是同一个')
        }
      }
    },

    // 子拖动
    handleDragStart (e, item, index, _index) {
      this.newDrag = false
      this.parentDragging = null
      this.dragging = Object.assign({}, item, {index: index, _index: _index})
    },
    handleDragEnd (e, item) {
      if (this.ending.key != this.dragging.key) {
        return
      }
      let sourceIndex = this.dragging._index
      let targetIndex = this.ending._index
      let parentInex = this.dragging.index
      this.dataList[parentInex].children[sourceIndex] = this.dataList[parentInex].children.splice(targetIndex, 1, this.dataList[parentInex].children[sourceIndex])[0]
    },
    handleDragOver (e, item, index, _index) {
      // e.dataTransfer.dropEffect = 'move'
      //判断子类移入
      if (this.dragging) {
        if (this.ending.key != this.dragging.key) {
          e.dataTransfer.dropEffect = 'none'
        } else {
          e.dataTransfer.dropEffect = 'move'
        }
      }
    },
    handleDragEnter (e, item, index, _index) {
      // 为需要移动的元素设置dragstart事件
      e.dataTransfer.effectAllowed = 'move'
      this.ending = Object.assign({}, item, {index: index, _index: _index})
    },

    editTitle (index, bool) {
      this.dataList[index].showTitleEdit = bool
      this.$nextTick(() => {
        this.$refs['editInput' + index][0].focus()
      })
    },
    deleteItem (index, rowIndex) {
      this.dataList[index].children.splice(rowIndex, 1)
    },
    getD () {
      console.log(this.dataList)
    }
  }
}
</script>

<style scoped lang="less">
.right_list, .left_list {
  width: 49%;
  padding: 10px;
  display: inline-block;
  vertical-align: top;

  h2 {
    font-size: 1.5em;
    margin: 20px 20px 10px;
  }

  p {
    padding: 10px;
    display: inline-block;
    width: 48%;
    text-align: center;
    cursor: pointer;
  }
}

.left_list {
  background: #bcf5de;

  ._flex {
    margin: 10px;
    display: inline-block;
    width: 45%;
    vertical-align: top;
  }

  .list_wrap {
    margin-bottom: 10px;
    border: 1px solid red;
  }
}

.right_list {
  background: #fdbfab;
}
</style>
View Code

 

 

posted @ 2022-05-30 15:54  小旺同学  阅读(370)  评论(0编辑  收藏  举报