vue和H5 draggable實(shí)現(xiàn)拖拽并替換效果
前言
公司項(xiàng)目需要做拖拽替換效果,本人用的vue框架。在網(wǎng)上找了很多資料都是用的 Vue.Draggable(git地址)。但這個(gè)組件實(shí)現(xiàn)的拖拽后插入效果,我倒騰了很久也沒有替換效果(如果Vue.Draggable能實(shí)現(xiàn)拖拽替換效果的話請(qǐng)大神給我留言)。
JQ有實(shí)現(xiàn)拖拽的插件,我下載過一個(gè)插件并看過源碼,大致原理是給目標(biāo)元素設(shè)置定位屬性,通過監(jiān)聽鼠標(biāo)mousedown,mouseup事件,再計(jì)算鼠標(biāo)位置變化,然后給元素樣式設(shè)置偏移值來實(shí)現(xiàn)拖拽效果的。
H5提供了專門的拖拽API 給元素添加 draggable 屬性,設(shè)置為 true就能實(shí)現(xiàn)拖拽了。本文使用的H5提供的拖拽API 以及vue 無(wú)其他任何添加,請(qǐng)放心使用
直接上代碼
<template> <div class="container"> <div class="layout"> <button class="layout-btn" @click="layoutType=val.value" v-for="val in layoutOptions" :key="val.value" >{{val.label}}</button> </div> <div class="group" :class="{'left-top-container': gindex===0, 'right-top-container': gindex===1, 'bottom-container': gindex===2, 'top-container': gindex<2}" v-for="(group,gindex) in data" :key="gindex" > <div class="cls-default" v-for="(item,cindex) in group.children" :key="cindex" :data-id="gindex+'-'+cindex" draggable="true" @dragstart="onDragstart($event)" @dragend="onDragend($event)" @dragover="onDragover($event)" @drop="onDrop($event)" :style="{'background-color': item.color}" :class="{'cls1-0': cindex ===0 && layoutType==1, 'cls2-0': (cindex ===0 || cindex ===1) && layoutType==2, 'cls3-0': cindex ===0 && layoutType==3, 'cls3-1': (cindex ===1 || cindex ===2) && layoutType==3, 'cls4-0': cindex <4 && layoutType==4, 'cls6-0': cindex === 0 && layoutType==6 }" > <div class="content">{{item.color ? item.color : '我是空對(duì)象'}}</div> </div> </div> <div class="tips">上面兩個(gè)區(qū)域內(nèi)是展示區(qū)的內(nèi)容能互相拖拽 <br>下面的是資源區(qū),只能復(fù)制出去覆蓋目標(biāo)區(qū)域,本身不會(huì)被替換掉 </div> </div> </template> <script> export default { data() { return { stargindex: "", endIndex: "", layoutType: "9", layoutOptions: [ { label: "單分屏", value: 1 }, { label: "二分屏", value: 2 }, { label: "三分屏", value: 3 }, { label: "四分屏", value: 4 }, { label: "六分屏", value: 6 }, { label: "九分屏", value: 9 } ], data: [ { group: "left-show", title: "視頻播放區(qū)一", children: [ { id: 6, color: "orange" }, { id: 2, color: "yellow" }, {}, {}, {}, {}, { id: 3, color: "cyan" }, {}, { id: 5, color: "brown" } ] }, { group: "right-show", title: "視頻播放區(qū)二", children: [ {}, { id: 7, color: "pink" }, {}, {}, { id: 4, color: "purple" }, {}, {}, {}, { id: 10, color: "gray" } ] }, { group: "source", title: "視頻資源區(qū)", children: [ { id: 11, color: "white" }, { id: 12, color: "black" }, { id: 13, color: "red" }, { id: 14, color: "green" }, { id: 15, color: "blue" } ] } ] }; }, methods: { onDragstart(event) { this.stargindex = event.target.getAttribute("data-id"); }, onDragend(event) { let startGroupIndex = this.stargindex.split("-")[0]; let startChildIndex = this.stargindex.split("-")[1]; let endGroupIndex = this.endIndex.split("-")[0]; let endChildIndex = this.endIndex.split("-")[1]; // 對(duì)數(shù)據(jù)做簡(jiǎn)單的深拷貝 目前不需要 // let endObj = JSON.parse( // JSON.stringify(this.data[endGroupIndex].children[endChildIndex]) // ); // let startObj = JSON.parse( // JSON.stringify(this.data[startGroupIndex].children[startChildIndex]) // ); let endObj = this.data[endGroupIndex].children[endChildIndex]; let startObj = this.data[startGroupIndex].children[startChildIndex]; if (this.data[endGroupIndex].group === "source") { //往資源區(qū)拖拽時(shí) 不做任何替換操作 return; } this.data[endGroupIndex].children.splice(endChildIndex, 1, startObj); if (this.data[startGroupIndex].group !== "source") { //拖拽起始區(qū)域不是 source時(shí) 把起始區(qū)域替換成拖拽后區(qū)域的數(shù)據(jù) this.data[startGroupIndex].children.splice(startChildIndex, 1, endObj); } }, onDrop(event) { if (event.target.className.indexOf("cls-default") > -1) { this.endIndex = event.target.getAttribute("data-id"); } else { this.endIndex = event.target.parentElement.getAttribute("data-id"); } }, onDragover(event) { event.preventDefault(); } } }; </script> <style scoped> .container { background-color: #eee; height: 800px; } .layout .layout-btn { background-color: #409eff; color: #fff; padding: 10px 15px; margin: 10px 15px; } .tips { font-size: 24px; text-align: center; } .group { float: left; overflow: hidden; box-sizing: border-box; } .group-title { height: 40px; line-height: 40px; } .cls-default { float: left; margin: 0; box-sizing: border-box; overflow: hidden; border: 1px solid #999; } .cls-default .content { text-align: center; padding-top: 20px; font-size: 20px; } .top-container { height: 400px; width: 40%; margin: 15px 5%; } .top-container .cls-default { width: 33.33%; height: 33.33%; } .top-container .cls1-0 { width: 100%; height: 100%; } .top-container .cls2-0 { width: 50%; height: 100%; } .top-container .cls3-0 { width: 50%; height: 100%; } .top-container .cls3-1 { width: 50%; height: 50%; } .top-container .cls4-0 { width: 50%; height: 50%; } .top-container .cls6-0 { width: 66.66%; height: 66.65%; } .bottom-container { width: 90%; height: 200px; margin: 15px 5%; } .bottom-container .cls-default { width: 15%; height: 150px; } </style>
寫在最后
本文是我第一次寫博客,寫的比較隨意,樣式處理也是很隨心。如有錯(cuò)誤請(qǐng)指正。
后面有時(shí)間會(huì)完善組件的功能。參考Vue.Draggable(git地址)這個(gè)組件。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue中el-tab如何點(diǎn)擊不同標(biāo)簽觸發(fā)不同函數(shù)的實(shí)現(xiàn)
el-tab本身的功能是點(diǎn)擊之后切換不同頁(yè),本文主要介紹了vue中el-tab如何點(diǎn)擊不同標(biāo)簽觸發(fā)不同函數(shù)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03詳解vue2.0 使用動(dòng)態(tài)組件實(shí)現(xiàn) Tab 標(biāo)簽頁(yè)切換效果(vue-cli)
本篇文章主要介紹了詳解vue2.0 使用動(dòng)態(tài)組件實(shí)現(xiàn) Tab 標(biāo)簽頁(yè)切換效果(vue-cli),具有一定的參考價(jià)值,有需要的可以了解下2017-08-08簡(jiǎn)單了解vue中的v-if和v-show的區(qū)別
這篇文章主要介紹了簡(jiǎn)單了解vue中的v-if和v-show的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10解決VUE3 keep-alive頁(yè)面切換報(bào)錯(cuò)parentComponent.ctx.deactivate
這篇文章主要介紹了解決VUE3 keep-alive頁(yè)面切換報(bào)錯(cuò)parentComponent.ctx.deactivate is not a function的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue多組件倉(cāng)庫(kù)開發(fā)與發(fā)布詳解
這篇文章主要介紹了Vue多組件倉(cāng)庫(kù)開發(fā)與發(fā)布詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02vue實(shí)現(xiàn)GitHub的第三方授權(quán)方法示例
本文主要介紹了vue實(shí)現(xiàn)GitHub的第三方授權(quán),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11一次前端Vue項(xiàng)目國(guó)際化解決方案的實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了關(guān)于前端Vue項(xiàng)目國(guó)際化解決方案的實(shí)戰(zhàn)記錄,以上只是一部分Vue項(xiàng)目開發(fā)中遇到的典型問題和解決方案,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07