Vue H5拖拽实例

需求:需要把左侧的数据表,拖拽到右侧的表关联区域

 

 

左侧数据表HTML:

<h3 class="data-block">数据表</h3>
<a-input-search placeholder="输入关键词搜索" @search="handleSearchTable" style="width: 90%;" />
<p style="margin-top: 10px;">
  <ul class="data-table-list">
    <li
      v-for="(item, index) in dataTableFilterResult"
      :key="index"
      draggable="true"
      @dragstart="onDragstartTable($event, item)"
      @dragend="onDragendTable($event)"
    >
      {{ item }}
    </li>
  </ul>
</p>

关键在于需要在允许拖拽的元素上设置draggable属性为true,表示允许拖拽,然后定义两个事件,dragstartdragend,用于处理拖拽事件。

dragstart事件是拖拽开始时触发,用于在拖拽时将数据存储到事件的dataTransfer数据容器中。

dragend事件是拖拽结束后触发,不管是否拖拽成功(可以理解为不管是否已经拖拽到目标区域)。

 

// 拖拽开始
onDragstartTable (event, item) {
  // console.log('------dragstart------')
  if (this.browserType().name === 'FF') {
      // 兼容火狐浏览器,火狐拖拽必须携带数据
      event.dataTransfer.setData('tableName', item)
  }
  // 指示拖拽的目标区域
  this.$refs.tableRelationArea.style.border = '2px red dashed'
  // 存储拖拽传输的数据
  event.dataTransfer.setData('tableName', item)
  console.log('drag tableName', item)
},
// 拖拽结束后触发,不管是否拖拽成功
onDragendTable (event) {
  // console.log('------dragend------')
  // 隐藏拖拽目标区域指示
  this.$refs.tableRelationArea.style.border = '1px #d2cfcf45 solid'
},

 

最后设置拖拽的目标区域,HTML如下:

<div style="min-height: 200px; margin-bottom: 10px;">
  <div>
    <h3 class="data-block" style="display: inline-block;">表关联</h3>
    <a-popconfirm :title="`确定清空所有数据表关联吗?`" @confirm="handleClearTableConnect">
      <a style="display: inline-block; margin-left: 10px;">清空关联</a>
    </a-popconfirm>
  </div>
  <div
    ref="tableRelationArea"
    @dragover.prevent
    @drop.prevent="onDropTable"
    style="height: 150px; border: 1px #d2cfcf45 solid; overflow-y: auto;"
  >
    <a-tree
      v-if="tableRelationData.mainTable !== ''"
      ref="folderTree"
      :treeData="tableTreeData"
      :expandedKeys="tableConnectExpandedKeys"
      :selectedKeys="tableConnectSelectedKeys"
      :autoExpandParent="tableConnectAutoExpandParent"
      showLine
      show-icon
      @expand="onFolderTreeExpand"
      @select="onFolderTreeSelect">
      <a-icon slot="switcherIcon" type="down" />
      <!-- <a-icon slot="folder" type="folder" /> -->
    </a-tree>
    <a-empty v-else description="请将左侧表拖放至此" style="position: relative; top: 50%; transform: translateY(-50%);"></a-empty>
  </div>
</div>

关键在于定义dragover和drop两个方法,dragover事件无需处理逻辑,但需要设置阻止冒泡,即:dragover.preventdrop事件也需要设置阻止冒泡。

drop事件是松开鼠标完成拖拽后触发,用于获取拖拽时传输的数据,然后对数据进行处理,JS如下:

 

// 松开鼠标完成拖拽后触发
onDropTable (event, target) {
  // console.log('------drop------')
  // 获取拖拽携带的数据
  const tableName = event.dataTransfer.getData('tableName')
  console.log('drop tableName', tableName)
  // 渲染数据
  this.renderData(tableName)
},

 

完整的效果:

 

完整的代码:

<h3 class="data-block">数据表</h3>
<a-input-search placeholder="输入关键词搜索" @search="handleSearchTable" style="width: 90%;" />
<p style="margin-top: 10px;">
  <ul class="data-table-list">
    <li
      v-for="(item, index) in dataTableFilterResult"
      :key="index"
      draggable="true"
      @dragstart="onDragstartTable($event, item)"
      @dragend="onDragendTable($event)"
    >
      {{ item }}
    </li>
  </ul>
</p>

<div style="min-height: 200px; margin-bottom: 10px;">
  <div>
    <h3 class="data-block" style="display: inline-block;">表关联</h3>
    <a-popconfirm :title="`确定清空所有数据表关联吗?`" @confirm="handleClearTableConnect">
      <a style="display: inline-block; margin-left: 10px;">清空关联</a>
    </a-popconfirm>
  </div>
  <div
    ref="tableRelationArea"
    @dragover.prevent
    @drop.prevent="onDropTable"
    style="height: 150px; border: 1px #d2cfcf45 solid; overflow-y: auto;"
  >
    <a-tree
      v-if="tableRelationData.mainTable !== ''"
      ref="folderTree"
      :treeData="tableTreeData"
      :expandedKeys="tableConnectExpandedKeys"
      :selectedKeys="tableConnectSelectedKeys"
      :autoExpandParent="tableConnectAutoExpandParent"
      showLine
      show-icon
      @expand="onFolderTreeExpand"
      @select="onFolderTreeSelect">
      <a-icon slot="switcherIcon" type="down" />
      <!-- <a-icon slot="folder" type="folder" /> -->
    </a-tree>
    <a-empty v-else description="请将左侧表拖放至此" style="position: relative; top: 50%; transform: translateY(-50%);"></a-empty>
  </div>
</div>
// 拖拽开始
onDragstartTable (event, item) {
  // console.log('------dragstart------')
  if (this.browserType().name === 'FF') {
      // 兼容火狐浏览器,火狐拖拽必须携带数据
      event.dataTransfer.setData('tableName', item)
  }
  // 指示拖拽的目标区域
  this.$refs.tableRelationArea.style.border = '2px red dashed'
  // 存储拖拽传输的数据
  event.dataTransfer.setData('tableName', item)
  console.log('drag tableName', item)
},
// 拖拽结束后触发,不管是否拖拽成功
onDragendTable (event) {
  // console.log('------dragend------')
  // 隐藏拖拽目标区域指示
  this.$refs.tableRelationArea.style.border = '1px #d2cfcf45 solid'
},
// 松开鼠标完成拖拽后触发
onDropTable (event, target) {
  // console.log('------drop------')
  // 获取拖拽携带的数据
  const tableName = event.dataTransfer.getData('tableName')
  console.log('drop tableName', tableName)
  // 渲染数据
  this.renderData(tableName)
},

 

posted @ 2020-06-02 11:06  jardeng  阅读(1658)  评论(0编辑  收藏  举报