PC端,基于vue框架,通过原生api实现的拖动效果
一、使用addEventListener实现,要手动解绑事件
<template>
<div id="app" ref="app">
<!--draggable设置为true才可以拖动-->
<div class="box" :ref="`box${index}`" v-if='list' v-for="(item,index) in list" draggable="true"
:index="index" :key="index">
<div>{{item.title}}</div>
<div>{{item.content}}</div>
<img :src="item.imgUrl" alt="海报" width="130" height="100" draggable="false">
</div>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
list: [
{
title: '海贼王1',
content: 'one-price',
imgUrl: 'https://up.enterdesk.com/edpic/bd/8a/ca/bd8aca7a116c0df1840412b225b46e32.jpg',
},
{
title: '火影忍者2',
content: '全村的希望',
imgUrl: 'https://images7.alphacoders.com/303/thumb-1920-303042.png',
},
{
title: '死神3',
content: 'Bleach',
imgUrl: 'https://up.enterdesk.com/edpic/dc/33/a1/dc33a1ee8bb76fa36c208eda48d0db47.jpg',
},
{
title: '柯南4',
content: 'Conan',
imgUrl: 'http://img.netbian.com/file/20110424/8fa978fe788dec3409e9fa621863120b.jpg',
},
],
};
},
mounted() {
this.addMoveEvent(this.$refs.app);
},
beforeDestroy() {
this.removeMoveEvent(this.$refs.app);
},
methods: {
swapArray(arr, index1, index2) {
arr[index2] = arr.splice(index1, 1, arr[index2])[0];
return arr;
},
dropFn(e) {
if (this.searchParents(e.target, 'box')) {
this.swapArray(this.list, e.target.getAttribute('index'), e.dataTransfer.getData('index'))
}
},
searchParents(ele, className) {
if (ele.className === className) {
return true;
}
else if (ele.tagName.toLocaleLowerCase() === 'body') {
return false;
}
else {
return this.searchParents(ele.parentNode, className);
}
},
dragstartFn(e) {
if (e.target.className === 'box') {
e.dataTransfer.setData('index', e.target.getAttribute('index'));
}
},
preventDefaultFn(e) {
e.preventDefault();
},
addMoveEvent(ele) {
ele.addEventListener('drop', this.dropFn, true);
ele.addEventListener('dragstart', this.dragstartFn, true);
ele.addEventListener('dragover', this.preventDefaultFn, true);
ele.addEventListener('dragenter', this.preventDefaultFn, true);
},
removeMoveEvent(ele) {
ele.removeEventListener('drop', this.dropFn,);
ele.removeEventListener('dragstart', this.dragstartFn);
ele.removeEventListener('dragover', this.preventDefaultFn);
ele.removeEventListener('dragenter', this.preventDefaultFn);
}
}
}
</script>
<style>
#app {
}
.box {
margin-right: 20px;
margin-bottom: 20px;
display: inline-block;
border: 1px solid #000;
width: 200px;
height: 200px;
}
</style>
二、使用vue组件实例相关api实现
<template>
<div id="app">
<div class="main"
@drop='drop($event)'
@dragstart="dragstart($event)"
@dragover.prevent
@dragenter.prevent
>
<!--draggable设置为true才可以拖动-->
<div class="box" :ref="`box${index}`"
v-if='list'
v-for="(item,index) in list" draggable="true"
:index="index" :key="index">
<div>{{item.title}}</div>
<div>{{item.content}}</div>
<img :src="item.imgUrl" alt="海报" width="130" height="100" draggable="false">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
list: null,
};
},
created() {
let timer = setTimeout(() => {
this.list = [
{
title: '海贼王1',
content: 'one-price',
imgUrl: 'https://up.enterdesk.com/edpic/bd/8a/ca/bd8aca7a116c0df1840412b225b46e32.jpg',
},
{
title: '火影忍者2',
content: '全村的希望',
imgUrl: 'https://images7.alphacoders.com/303/thumb-1920-303042.png',
},
{
title: '死神3',
content: 'Bleach',
imgUrl: 'https://up.enterdesk.com/edpic/dc/33/a1/dc33a1ee8bb76fa36c208eda48d0db47.jpg',
},
{
title: '柯南4',
content: 'Conan',
imgUrl: 'http://img.netbian.com/file/20110424/8fa978fe788dec3409e9fa621863120b.jpg',
},
];
}, 500)
},
methods: {
swapArray(arr, index1, index2) {
arr[index2] = arr.splice(index1, 1, arr[index2])[0];
return arr;
},
searchParents(ele, className) {
if (ele.className === className) {
return {
qualified: true,
ele,
};
}
else if (ele.tagName.toLocaleLowerCase() === 'body') {
return {
qualified: false,
ele: undefined,
};
}
else {
return this.searchParents(ele.parentNode, className);
}
},
drop(e) {
if (this.searchParents(e.target, 'box').qualified) {
this.swapArray(this.list, this.searchParents(e.target, 'box').ele.getAttribute('index'), e.dataTransfer.getData('index'))
}
},
dragstart(e) {
if (e.target.className === 'box') {
e.dataTransfer.setData('index', e.target.getAttribute('index'));
}
},
}
}
</script>
<style>
.box {
margin-right: 20px;
margin-bottom: 20px;
display: inline-block;
border: 1px solid #000;
width: 200px;
height: 200px;
}
</style>