vue實(shí)現(xiàn)圖片拖動(dòng)排序
本文實(shí)例為大家分享了vue實(shí)現(xiàn)圖片拖動(dòng)排序的具體代碼,供大家參考,具體內(nèi)容如下
原理:現(xiàn)有一個(gè)圖片的列表,拖動(dòng)其中一個(gè)圖片(觸發(fā)dragstart),當(dāng)拖動(dòng)的圖片移動(dòng)到其他圖片的位置(觸發(fā)dragover),則將拖動(dòng)的圖片從原位置移動(dòng)到該位置(觸發(fā)dragend)。
dragstart:當(dāng)用戶開(kāi)始拖動(dòng)一個(gè)元素或者一個(gè)選擇文本的時(shí)候 dragstart 事件就會(huì)觸發(fā)。
dragover:當(dāng)元素或者選擇的文本被拖拽到一個(gè)有效的放置目標(biāo)上時(shí),觸發(fā) dragover 事件(每幾百毫秒觸發(fā)一次)。
dragend:拖放事件在拖放操作結(jié)束時(shí)觸發(fā)。(我們這里可以不用)
(1)圖片列表HTML結(jié)構(gòu)。給需要拖動(dòng)的元素添加屬性draggable。這里要注意:模板for循環(huán)的key值需要唯一,因?yàn)関ue在渲染的時(shí)候會(huì)采用就地復(fù)用的方式,如果key值唯一,重新排序后渲染的列表節(jié)點(diǎn)不會(huì)復(fù)用,這樣可以避免一些問(wèn)題。(我們?cè)诓迦氲臅r(shí)候會(huì)根據(jù)序號(hào)向數(shù)組中插入某個(gè)數(shù)據(jù))
<ul class="drag-container"
@dragstart="onDragStart"
@dragover="onDragOver"
@dragend="onDragEnd"
ref="imgList">
<li
v-for="(item,idx) in list"
:key='item.path'
class="drag-list"
draggable="true"
>
<img :src="item.path" alt="" />
</li>
</ul>
(2)事件: dragstart、dragover綁定事件onDragStart、onDragOver
onDragStart:識(shí)別需要拖動(dòng)的元素,保存到狀態(tài)中,供拖動(dòng)過(guò)程中dragover的綁定事件使用。
onDragStart(event){
console.log("start");
this.draging = event.target;
},
onDragOver:拖動(dòng)過(guò)程中處于有效目標(biāo)上的時(shí)候觸發(fā)事件,識(shí)別的是目標(biāo)元素,而不是拖動(dòng)的元素。首先識(shí)別目標(biāo)元素是否是我們需要的目標(biāo)元素,我們例子判斷是否是li元素,并判斷圖片是否與拖動(dòng)的相同,則進(jìn)行插入拖動(dòng)元素的操作。
識(shí)別拖動(dòng)元素與目標(biāo)元素的位置序號(hào),將拖動(dòng)元素插入到目標(biāo)元素前,再將拖動(dòng)元素原位置的數(shù)據(jù)刪除,在vue中,則只需要進(jìn)行數(shù)據(jù)操作即可。
onDragOver(event){
console.log('drag move')
event.preventDefault();
let target = event.target;
//因?yàn)閐ragover會(huì)發(fā)生在ul上,所以要判斷是不是li
if (target.nodeName === "LI" &&
target.childNodes[0].src !== this.draging.childNodes[0].src) {
let idx_drag = this._index(this.draging)
let idx_target = this._index(target)
let _list = this.list
let _drag = this.list[idx_drag]
if(idx_drag>idx_target){
_list.splice(idx_target,0,_list[idx_drag]);
_list.splice(idx_drag+1,1)
}else{
_list.splice(idx_target+1,0,_list[idx_drag]);
_list.splice(idx_drag,1)
}
console.log(_list[0].path)
this.$emit("change", _list)
}
},
完整代碼如下:
<template>
<div class="image-list" v-if="list && list.length">
<ul class="drag-container"
@dragstart="onDragStart"
@dragover="onDragOver"
@dragend="onDragEnd"
ref="imgList">
<li
v-for="(item,idx) in list"
:key='item.path'
class="drag-list"
draggable="true"
>
<img :src="item.path" alt="" />
</li>
</ul>
</div>
</template>
<script>
export default {
name:"drag-image-list",
props:{
list: Array,
},
data(){
return {
draging:null,//被拖拽的對(duì)象
}
},
methods:{
onDragStart(event){
console.log("start");
this.draging = event.target;
},
onDragOver(event){
console.log('drag move')
event.preventDefault();
let target = event.target;
//因?yàn)閐ragover會(huì)發(fā)生在ul上,所以要判斷是不是li
if (target.nodeName === "LI" && target.childNodes[0].src !== this.draging.childNodes[0].src) {
let idx_drag = this._index(this.draging)
let idx_target = this._index(target)
let _list = this.list
let _drag = this.list[idx_drag]
if(idx_drag>idx_target){
_list.splice(idx_target,0,_list[idx_drag]);
_list.splice(idx_drag+1,1)
}else{
_list.splice(idx_target+1,0,_list[idx_drag]);
_list.splice(idx_drag,1)
}
console.log(_list[0].path)
}
},
onDragEnd(event){
console.log('end event')
},
_index(el){
var index = 0;
if (!el || !el.parentNode) {
return -1;
}
while (el && (el = el.previousElementSibling)) {
index++;
}
return index;
},
}
}
</script>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue項(xiàng)目通過(guò)a標(biāo)簽下載圖片至zip包的示例代碼
在vue項(xiàng)目中,將圖片下載可使用流的形式,下載成單個(gè)圖片,或者將多個(gè)圖片下載至zip包,本文就是介紹使用a標(biāo)簽下載圖片的用法,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-10-10
Vue實(shí)現(xiàn)導(dǎo)航欄點(diǎn)擊當(dāng)前標(biāo)簽變色功能
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)導(dǎo)航欄點(diǎn)擊當(dāng)前標(biāo)簽變色功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
vue3常用響應(yīng)式對(duì)象的api,你全用過(guò)了嗎
這篇文章主要給大家介紹了關(guān)于vue3常用響應(yīng)式對(duì)象api的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue3具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02
element-ui中dialog彈窗關(guān)閉按鈕失效的解決
這篇文章主要介紹了element-ui中dialog彈窗關(guān)閉按鈕失效的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
elementUI?el-table二次封裝的詳細(xì)實(shí)例
在項(xiàng)目中會(huì)多次使用表格展示數(shù)據(jù),不對(duì)這個(gè)table進(jìn)行二次封裝成我們自己想要的,重復(fù)的代碼量的工作會(huì)比較大,下面這篇文章主要給大家介紹了關(guān)于elementUI?el-table二次封裝的相關(guān)資料,需要的朋友可以參考下2023-03-03
Vue框架+Element-ui(el-upload組件)使用http-request方法上傳文件并顯示文件上傳進(jìn)度功能
這篇文章主要介紹了Vue框架+Element-ui(el-upload組件)使用http-request方法上傳文件并顯示文件上傳進(jìn)度功能,本通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08
mpvue跳轉(zhuǎn)頁(yè)面及注意事項(xiàng)
這篇文章主要介紹了mpvue跳轉(zhuǎn)頁(yè)面及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2018-08-08

