1. 程式人生 > >vue中實現基礎元件——拖拽元件

vue中實現基礎元件——拖拽元件

前言

pc端開發需要拖拽元件完成列表的順序交換,一般移動端的UI元件會包含,但是我在用的iview並沒有此功能的元件,於是手寫一個,實現起來很簡單。效果圖如下:
拖拽元件效果圖
可以拖拽完成新排序,點選某一項可以觸發相關事件.

關於拖拽 drag & drop

拖放(Drag 和 drop)是 HTML5 標準的組成部分。

  • 拖拽物件
    dataTransfer物件,只能在拖放事件的事件處理程式中訪問。重要屬性:
    • effectAllowed ( none | copy | copyLink | copyMove | link、linkMove | move | all | uninitialized ):設定或返回被拖動元素允許發生的拖動行為。
    • dropEffect( none | copy | link | move ):設定或返回拖放目標上允許發生的拖放行為。如果此設定的拖放行為不在effectAllowed屬性設定的多種拖放行為之內,拖放操作將會失敗。
    • dataTransfer.getData(format):獲取DataTransfer物件中設定format格式的資料。其中format代表資料格式,data代表資料。
  • 拖拽屬性
    draggable 屬性規定元素是否可拖動。
  • 拖拽事件
    • ondragstart
      在拖動開始時執行,返回被拖動元素。
    • ondragover
      返回在何處放置被拖動的資料
      預設地,無法將資料/元素放置到其他元素中。如果需要設定允許放置,我們必須阻止對元素的預設處理方式
    • ondragenter
      在被拖動的元素進入到放置目標時執行
    • ondragleave
      在被拖動的元素離開放置目標時執行
    • ondragend && ondrop
      皆指滑鼠鬆開被拖動物件的事件,但是返回的分別為被拖動物件和被拖動元素懸掛的那個元素

原始碼

<template>
  <div class="transition-container">
      <div class="item" v-for="(item, index) in items" :key="index"
        draggable="true"
        @dragstart=
"handleDragStart($event, item)" @dragover.prevent="handleDragOver($event, item)" @dragenter="handleDragEnter($event, item)" @dragend="handleDragEnd($event, item)" @click="chooseNav(item)" > <p class="trans-btn"> <span v-if="item.problemId"> <b class="id"> {{item.problemId}} </b> {{item.key}} </span> <span v-else> {{item.key}} </span> <span> <i-button v-if="btn" size="small" type="error" style="margin-right: 10px;" @click="deleteItem(item, index)">刪除</i-button> </span> </p> </div> </div> </template> <script> import './index.less'; export default { name: 'transition', props: { dataSource: Array, btn: Boolean, }, data() { return { items: [], dragging: null, }; }, watch: { dataSource(val) { this.items = val; }, dragging(val) { if (this.dataSource.includes(val)) { this.dragging = val; } else { this.dragging = null; } }, }, methods: { handleDragStart(e, item) { this.dragging = item; }, handleDragEnd() { this.dragging = null; this.$emit('hasChanged', this.items); }, // 首先把div變成可以放置的元素,即重寫dragenter/dragover handleDragOver(e) { e.dataTransfer.dropEffect = 'move';// e.dataTransfer.dropEffect="move";//在dragenter中針對放置目標來設定! }, handleDragEnter(e, item) { if (this.dragging) { e.dataTransfer.effectAllowed = 'move';// 為需要移動的元素設定dragstart事件 if (item === this.dragging) { return; } const newItems = [...this.items]; console.log(newItems); const src = newItems.indexOf(this.dragging); const dst = newItems.indexOf(item); newItems.splice(dst, 0, ...newItems.splice(src, 1)); this.items = newItems; } }, chooseNav(val) { this.$emit('selectItem', val); }, deleteItem(item, index) { this.$emit('deleteItem', item, index); }, editor(item, index) { this.$emit('editorItem', item, index); }, }, }; </script>

基本功能就完成啦

參考文章

如果簡單的功能不能滿足,推薦這個寫好的輪子