需求:需要把左側的數據表,拖拽到右側的表關聯區域
左側數據表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,表示允許拖拽,然后定義兩個事件,dragstart和dragend,用於處理拖拽事件。
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.prevent,drop事件也需要設置阻止冒泡。
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) },