使用vue-grid-layout完成桌面拖拽布局功能(实现两个元素互换位置)
最近有个项目需要实现和windows桌面类似的图标拖拽功能,找了很多组件都没找到一个合适的,但通过本博主的不懈努力最后发现了两款不错的插件:sortablejsvue-grid-layout本来一开始我使用的是第一个,但是可能是有点转不过来,最终放弃了第一个插件,但是第二个也确实香,虽然也有不少bug但是也不是不能解决的,下面就回到正题上来给大家粗略说一下:先上代码吧,怕大家等不及往下拉:<
·
最近有个项目需要实现和windows桌面类似的图标拖拽功能,找了很多组件都没找到一个合适的,但通过本博主的不懈努力最后发现了两款不错的插件:
- sortablejs
- vue-grid-layout
本来一开始我使用的是第一个,但是可能是有点转不过来,最终放弃了第一个插件,但是第二个也确实香,虽然也有不少bug但是也不是不能解决的,下面就回到正题上来给大家粗略说一下:
先上代码吧,怕大家等不及往下拉:
<template>
<div>
<grid-layout :layout.sync="layout"
:col-num="8"
:row-height="100"
:is-draggable="true"
:is-resizable="false"
:vertical-compact="false"
:margin="[20, 24]"
:use-css-transforms="true">
<grid-item v-for="(item,index) in layout"
:key="index"
:item="watchitem(item)"
:static="item.static"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
@move="moveEvent"
@moved="movedEvent" >
<span class="text">{{item.i}}</span>
</grid-item>
</grid-layout>
</div>
</template>
<script>
var historyLayout = [
{"x":0,"y":0,"w":1,"h":1,"i":"0", static: false},
{"x":1,"y":0,"w":1,"h":1,"i":"1", static: false},
{"x":2,"y":0,"w":1,"h":1,"i":"2", static: false},
{"x":3,"y":0,"w":1,"h":1,"i":"3", static: false},
{"x":4,"y":0,"w":1,"h":1,"i":"4", static: false},
{"x":5,"y":0,"w":1,"h":1,"i":"5", static: false},
{"x":6,"y":0,"w":1,"h":1,"i":"6", static: false},
{"x":7,"y":0,"w":1,"h":1,"i":"7", static: false},
{"x":0,"y":1,"w":1,"h":1,"i":"8", static: false},
{"x":1,"y":1,"w":1,"h":1,"i":"9", static: false},
{"x":2,"y":1,"w":1,"h":1,"i":"10", static: false},
{"x":3,"y":1,"w":1,"h":1,"i":"11", static: false},
{"x":4,"y":1,"w":1,"h":1,"i":"12", static: false},
{"x":5,"y":1,"w":1,"h":1,"i":"13", static: false},
{"x":6,"y":1,"w":1,"h":1,"i":"14", static: false},
{"x":7,"y":1,"w":1,"h":1,"i":"15", static: false},
{"x":0,"y":2,"w":1,"h":1,"i":"16", static: false},
{"x":1,"y":2,"w":1,"h":1,"i":"17", static: false},
{"x":2,"y":2,"w":1,"h":1,"i":"18", static: false},
{"x":3,"y":2,"w":1,"h":1,"i":"19", static: false}
];
import { GridLayout, GridItem } from "vue-grid-layout"
export default {
components: {
GridLayout,
GridItem
},
data() {
return {
layout: [
{"x":0,"y":0,"w":1,"h":1,"i":"0", static: false},
{"x":1,"y":0,"w":1,"h":1,"i":"1", static: false},
{"x":2,"y":0,"w":1,"h":1,"i":"2", static: false},
{"x":3,"y":0,"w":1,"h":1,"i":"3", static: false},
{"x":4,"y":0,"w":1,"h":1,"i":"4", static: false},
{"x":5,"y":0,"w":1,"h":1,"i":"5", static: false},
{"x":6,"y":0,"w":1,"h":1,"i":"6", static: false},
{"x":7,"y":0,"w":1,"h":1,"i":"7", static: false},
{"x":0,"y":1,"w":1,"h":1,"i":"8", static: false},
{"x":1,"y":1,"w":1,"h":1,"i":"9", static: false},
{"x":2,"y":1,"w":1,"h":1,"i":"10", static: false},
{"x":3,"y":1,"w":1,"h":1,"i":"11", static: false},
{"x":4,"y":1,"w":1,"h":1,"i":"12", static: false},
{"x":5,"y":1,"w":1,"h":1,"i":"13", static: false},
{"x":6,"y":1,"w":1,"h":1,"i":"14", static: false},
{"x":7,"y":1,"w":1,"h":1,"i":"15", static: false},
{"x":0,"y":2,"w":1,"h":1,"i":"16", static: false},
{"x":1,"y":2,"w":1,"h":1,"i":"17", static: false},
{"x":2,"y":2,"w":1,"h":1,"i":"18", static: false},
{"x":3,"y":2,"w":1,"h":1,"i":"19", static: false}
],
draggable: true,
resizable: true,
index: 0,
newX:0,
newY:0,
curBox:'',
}
},
methods: {
watchitem (item) {
if(this.curBox != item.i) {
for (let j = 0; historyLayout[j] != undefined; j++) {
if(historyLayout[j].i == item.i) {
item.x = historyLayout[j].x
item.y = historyLayout[j].y
}
}
}
return item
},
moveEvent (i){
this.curBox = i
},
movedEvent (i, newX, newY) {
for (let j = 0; historyLayout[j] != undefined; j++) {
if(historyLayout[j].i == i) {
this.newX = historyLayout[j].x
this.newY = historyLayout[j].y
historyLayout[j].x = newX
historyLayout[j].y = newY
}
}
for (let j = 0; historyLayout[j] != undefined; j++) {
if(i!=historyLayout[j].i && historyLayout[j].x === newX && historyLayout[j].y === newY) {
historyLayout[j].x = this.newX
historyLayout[j].y = this.newY
}
}
}
}
}
</script>
<style scoped>
.vue-grid-layout {
background: #eee;
}
.vue-grid-item:not(.vue-grid-placeholder) {
background: #ccc;
border: 1px solid black;
}
.vue-grid-item .resizing {
opacity: 0.9;
}
.vue-grid-item .static {
background: #cce;
}
.vue-grid-item .text {
font-size: 24px;
text-align: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height: 100%;
width: 100%;
}
.vue-grid-item .no-drag {
height: 100%;
width: 100%;
}
.vue-grid-item .minMax {
font-size: 12px;
}
.vue-grid-item .add {
cursor: pointer;
}
</style>
效果(本人是最看不惯别人的文章不带效果的,狗头保护…)
下面进入正文:
- 安装:
npm install vue-grid-layout --save
- 导入 && 引用
import VueGridLayout from 'vue-grid-layout';
export default {
components: {
GridLayout: VueGridLayout.GridLayout,
GridItem: VueGridLayout.GridItem
},
// ... data, methods, mounted (), etc.
}
-
属性 && 方法
这里就不做过多的讲解,毕竟文档比我写要好
属性 -
这里才最主要是新增代码
在vue-grid-layout
中的标识栅格元素是否可拖拽该属性只能将元素向下排,并不能形成左右替换的形式,并且在该组件中也没有元素互相替换位置这种属性,所以我给它加了判定
...
methods: {
watchitem (item) {
// 判断当前移动的对象是否导致其他元素发生位移变换
if(this.curBox != item.i) {
for (let j = 0; historyLayout[j] != undefined; j++) {
if(historyLayout[j].i == item.i) {
item.x = historyLayout[j].x
item.y = historyLayout[j].y
}
}
}
return item
},
moveEvent (i){
// 移动时记录当前移动的元素对象
this.curBox = i
},
movedEvent (i, newX, newY) {
// 将元素最新生成的位置记录在historyLayout中,用来形成判断
for (let j = 0; historyLayout[j] != undefined; j++) {
if(historyLayout[j].i == i) {
this.newX = historyLayout[j].x
this.newY = historyLayout[j].y
historyLayout[j].x = newX
historyLayout[j].y = newY
}
}
// 当元素移动到原本有元素的位置上时,原本位置上的元素迁移到移动前元素的位置上形成互换位置
for (let j = 0; historyLayout[j] != undefined; j++) {
if(i!=historyLayout[j].i && historyLayout[j].x === newX && historyLayout[j].y === newY) {
historyLayout[j].x = this.newX
historyLayout[j].y = this.newY
}
}
}
}
以上就是我目前功能的实现,但由于项目时间关系,还没有完善代码,没有写一个将元素插入其中的方法,希望各位有了更好的意见时可以一起分享分享
更多推荐
已为社区贡献5条内容
所有评论(0)