最近在用写公司项目里的一个桌面布局功能 须要使用到vue-grid-layout
看了下网上的 基本上只有demo的使用,这个插件虽然挺不错可是缺陷也很大.
没有下边界,发生碰撞的时候块会无限的往下移动
https://github.com/jbaysoluti...
先撸一遍demo吧css
<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里的vue
若是是否的话是使用绝对布局来排版的 和使用transforms排版有一点区别git
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用来搞事情github
修改下grid-item里 增长watchitemsegmentfault
<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()中调用一个调整位置的函数 使其能够达到 两两调换的效果 以及其余的移动效果 想了解的能够点击这里 this
还有一个比较须要注意的是针对对象的操做会比较多 对其操做时须要注意 更改的是自己的值仍是引用值url
最后大概实现成这样 有能力的大神仍是本身写一套比较好spa