vue中實現基礎元件——拖拽元件
阿新 • • 發佈:2019-01-27
前言
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
皆指滑鼠鬆開被拖動物件的事件,但是返回的分別為被拖動物件和被拖動元素懸掛的那個元素
- ondragstart
原始碼
<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>
基本功能就完成啦
參考文章
如果簡單的功能不能滿足,推薦這個寫好的輪子