最近在用寫公司項目裏的一個桌面佈局功能 須要使用到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