最近在用写公司项目里的一个桌面布局功能 需要使用到vue-grid-layout
看了下网上的 基本上只有demo的使用,这个插件虽然挺不错但是缺陷也很大.
没有下边界,发生碰撞的时候块会无限的往下移动
https://github.com/jbaysoluti...
先撸一遍demo吧
<template>
<grid-layout
:layout="layout"
:auto-size="false"
:col-num="20"
:row-height="50"
:max-rows="100"
:is-draggable="true"
:is-resizable="false"
:vertical-compact="false"
:margin="[10, 10]"
:use-css-transforms="true"
>
<grid-item v-for="item in layout" :key="item.i"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
@resize="resizeEvent"
@move="moveEvent"
@resized="resizedEvent"
@moved="movedEvent"
>
{{item.i}}
</grid-item>
</grid-layout>
</template>
<script>
import Vue from 'vue'
import VueGridLayout from 'vue-grid-layout'
Vue.use(VueGridLayout)
var testLayout = [
{"x":0,"y":0,"w":1,"h":1,"i":"0"},
{"x":0,"y":1,"w":1,"h":1,"i":"1"},
{"x":0,"y":2,"w":1,"h":1,"i":"2"},
{"x":0,"y":3,"w":1,"h":1,"i":"3"},
{"x":1,"y":0,"w":1,"h":1,"i":"4"},
{"x":1,"y":1,"w":1,"h":1,"i":"5"},
{"x":1,"y":2,"w":1,"h":1,"i":"6"},
{"x":1,"y":3,"w":1,"h":1,"i":"7"},
{"x":2,"y":0,"w":1,"h":1,"i":"8"},
{"x":2,"y":1,"w":1,"h":1,"i":"9"},
{"x":2,"y":2,"w":1,"h":1,"i":"10"},
{"x":2,"y":3,"w":1,"h":1,"i":"11"},
{"x":3,"y":0,"w":1,"h":1,"i":"12"},
{"x":3,"y":1,"w":1,"h":1,"i":"13"},
{"x":3,"y":2,"w":1,"h":1,"i":"14"},
{"x":3,"y":3,"w":1,"h":1,"i":"15"},
{"x":4,"y":0,"w":1,"h":1,"i":"16"},
{"x":4,"y":1,"w":1,"h":1,"i":"17"},
{"x":4,"y":2,"w":1,"h":1,"i":"18"},
{"x":4,"y":3,"w":1,"h":1,"i":"19"}
];
var GridLayout = VueGridLayout.GridLayout;
var GridItem = VueGridLayout.GridItem;
export default {
name: 'Layout',
components: {
GridLayout,
GridItem,
},
data () {
return {
layout: testLayout,
newX:0,
newY:0
}
},
mounted () {
},
methods:{
moveEvent: function(i, newX, newY,e){
//console.log(e)
//console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY);
},
resizeEvent: function(i, newH, newW){
//console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW);
},
movedEvent: function(i, newX, newY,e){
//console.log(e)
//console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY);
},
resizedEvent: function(i, newH, newW, newHPx, newWPx){
//console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.vue-grid-layout {
position: relative;
width:800px;
height:450px;
/*overflow: hidden;*/
background: url('../../assets/desktop_background.png') no-repeat;
}
.vue-grid-layout>div {
position: absolute;
background: indianred;
}
</style>
随便写点样式 页面大概是这样
options里的
- vertical-compact 是 垂直紧凑布局 就是拖动留空了 若下方有块会自动往上补
- use-css-transforms 是否使用css的transforms来排版 一般默认就好了 为true时是最终页面是这样的
如果是否的话是使用绝对布局来排版的 和使用transforms排版有一点区别
看下函数
moveEvent: function(i, newX, newY,e){
//console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY);
},
resizeEvent: function(i, newH, newW){
//console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW);
},
movedEvent: function(i, newX, newY,e){
//console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY);
},
resizedEvent: function(i, newH, newW, newHPx, newWPx){
//console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
}
现在用到的是moveEvent和movedEvent 一个是移动时就触发 一个是移动完成 松开鼠标的时候触发
可以通过这两个事件中的i用来搞事情
敲黑板划重点
修改下grid-item里 增加watchitem
<grid-item v-for="item in layout" :key="item.i"
:item="watchitem(item)"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
@resize="resizeEvent"
@move="moveEvent"
@resized="resizedEvent"
@moved="movedEvent"
>
{{item.i}}
</grid-item>
在methods 里增加 watchitem
watchitem:function(item) {
if(item.y>y_max ||item.x>x_max){
item.y=
item.x=
}
return item
}
这边通过移动完后快速遍历每一个item的信息来修改后 达到自己所需的效果
现在的效果是当你移动一个box时 即使你没松开鼠标 每一个被你移动中碰撞到的box都会发生改变 这可能不是我们想要的 可以创建一个historyLayout 拿来记录我们上一步的布局 我们在watchitem()里比较 如果不是当前操作的box 使其的位置保持不变,在moved()中调用一个调整位置的函数 使其可以达到 两两调换的效果 以及其他的移动效果 想了解的可以点击这里
还有一个比较需要注意的是针对对象的操作会比较多 对其操作时需要注意 更改的是本身的值还是引用值
最后大概实现成这样 有能力的大神还是自己写一套比较好
所有评论(0)