官网
Vue Grid Layout 适用Vue.js的栅格布局系统
jbaysolutions.github.io/vue-grid-la...
中文官网
jbaysolutions.github.io/vue-grid-la...
github地址
github地址releases下载
简易上手
安装
css
npm install vue-grid-layout --save
在组件中引入
javascript
import { GridLayout, GridItem } from 'vue-grid-layout'
也可以在 index.html 文件中引入 js 文件
xml
<script src="<%= BASE_URL %>static/javascript/vue-grid-layout.umd.js"></script>
然后在 main.js 入口文件中,引入。并且,全局注册。
javascript
// 引入 vue-grid-layout 组件
import VueGridLayout from 'vue-grid-layout';
// 全局注册组件
Vue.component('grid-layout', VueGridLayout.GridLayout);
Vue.component('grid-item', VueGridLayout.GridItem);
基础用法
响应式布局 layout
css
new Vue({
el: '#app',
data: {
layout: [
{"x":0,"y":0,"w":2,"h":2,"i":"0"},
{"x":2,"y":0,"w":2,"h":4,"i":"1"},
{"x":4,"y":0,"w":2,"h":5,"i":"2"},
{"x":6,"y":0,"w":2,"h":3,"i":"3"},
{"x":8,"y":0,"w":2,"h":3,"i":"4"},
{"x":10,"y":0,"w":2,"h":3,"i":"5"},
{"x":0,"y":5,"w":2,"h":5,"i":"6"},
{"x":2,"y":5,"w":2,"h":5,"i":"7"},
{"x":4,"y":5,"w":2,"h":5,"i":"8"},
{"x":6,"y":3,"w":2,"h":4,"i":"9"},
{"x":8,"y":4,"w":2,"h":4,"i":"10"},
{"x":10,"y":4,"w":2,"h":4,"i":"11"},
{"x":0,"y":10,"w":2,"h":5,"i":"12"},
{"x":2,"y":10,"w":2,"h":5,"i":"13"},
{"x":4,"y":8,"w":2,"h":4,"i":"14"},
{"x":6,"y":8,"w":2,"h":4,"i":"15"},
{"x":8,"y":10,"w":2,"h":5,"i":"16"},
{"x":10,"y":4,"w":2,"h":2,"i":"17"},
{"x":0,"y":9,"w":2,"h":3,"i":"18"},
{"x":2,"y":6,"w":2,"h":2,"i":"19"}
],
},
});
ruby
<grid-layout
:layout.sync="layout"
:col-num="12"
:row-height="30"
:is-draggable="true"
:is-resizable="true"
:is-mirrored="false"
:vertical-compact="true"
:margin="[10, 10]"
:use-css-transforms="true"
>
<grid-item v-for="item in layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i">
{{item.i}}
</grid-item>
</grid-layout>
属性说明
只说最基础,最常用的属性。其他的属性,可见官网传送门:
jbaysolutions.github.io/vue-grid-la...
GridLayout组件的属性:
layout
layout 是一个对象数组,
css
layout: [
{"x":0,"y":0,"w":2,"h":2,"i":"0"},
{"x":2,"y":0,"w":2,"h":4,"i":"1"}
]
每一条数据,必须 i, x, y, w 和 h
属性。在 GridItem 组件中,需要用到。
i 是元素的id唯一。
x是第几列。
y是第几行。
w是宽度,是 colWidth 的倍数。
h是高度,是 rowHeight 的倍数。
colNum
列数,默认为12
rowHeight
每一行的高度,单位是像素。
isDraggable
是否可拖拽。
isResizable
是否可调整大小。
除了属性,还有一些事件。事件,同样查看官网传送门:
jbaysolutions.github.io/vue-grid-la...
我只举一个例子,说明 resize
的用法。调整大小时的事件。
ini
@resize="resizeEvent"
当我调整某一个 GridItem 大小的时候,我希望相邻的 GridItem 的宽高,也发生改变。可以这么写:
ini
resizeEvent: function (i, newH, newW, newHPx, newWPx) {
const currentItem = this.layout.find(item => item.i === i);
const widthChange = newW - currentItem.w;
const heightChange = newH - currentItem.h;
currentItem.w = newW;
currentItem.h = newH;
this.handleWidthChange(currentItem, widthChange);
this.handleHeightChange(currentItem, heightChange);
},
handleWidthChange: function (currentItem, widthChange, ids = []) {
const rightNeighbors = this.layout.filter(item =>
item.i !== currentItem.i &&
item.y >= currentItem.y &&
item.y < currentItem.y + currentItem.h &&
item.x === currentItem.x + currentItem.w - widthChange
);
rightNeighbors.forEach(neighbor => {
neighbor.x = currentItem.x + currentItem.w;
let newWidth = neighbor.w - widthChange;
newWidth = Math.max(1, newWidth);
newWidth = Math.min(newWidth, this.numCols - neighbor.x);
neighbor.w = newWidth;
this.handleWidthChange(neighbor, widthChange);
});
const sameColumnBelowNeighbors = this.layout.filter(item =>
!ids.includes(item.i) &&
item.i !== currentItem.i &&
item.x === currentItem.x &&
item.y >= currentItem.y + currentItem.h
);
sameColumnBelowNeighbors.forEach(neighbor => {
if (!ids.includes(neighbor.i)) {
let newWidth = neighbor.w + widthChange;
newWidth = Math.max(1, newWidth);
newWidth = Math.min(newWidth, this.numCols - neighbor.x);
neighbor.w = newWidth;
ids.push(neighbor.i);
this.handleWidthChange(neighbor, widthChange, ids);
}
});
},
handleHeightChange: function (currentItem, heightChange, ids = []) {
const bottomNeighbors = this.layout.filter(item =>
!ids.includes(item.i) &&
item.i !== currentItem.i &&
item.x >= currentItem.x &&
item.x < currentItem.x + currentItem.w &&
item.y === currentItem.y + currentItem.h - heightChange
);
bottomNeighbors.forEach(neighbor => {
if (!ids.includes(neighbor.i)) {
if (heightChange > 0) {
neighbor.y = currentItem.y + currentItem.h;
let newHeight = neighbor.h - heightChange;
newHeight = Math.max(1, newHeight);
newHeight = Math.min(newHeight, this.numRows - neighbor.y);
neighbor.h = newHeight;
} else {
neighbor.y = currentItem.y + currentItem.h;
let newHeight = neighbor.h - heightChange;
newHeight = Math.max(1, newHeight);
newHeight = Math.min(newHeight, this.numRows - neighbor.y);
neighbor.h = newHeight;
}
ids.push(neighbor.i);
this.handleHeightChange(neighbor, heightChange, ids);
}
});
const sameRowRightNeighbors = this.layout.filter(item =>
!ids.includes(item.i) &&
item.i !== currentItem.i &&
item.y === currentItem.y &&
item.x > currentItem.x
);
sameRowRightNeighbors.forEach(neighbor => {
if (!ids.includes(neighbor.i)) {
let newHeight = neighbor.h;
if (heightChange > 0) {
if (currentItem.y + currentItem.h > neighbor.y + neighbor.h) {
newHeight = neighbor.h + heightChange;
}
} else {
if (currentItem.y + currentItem.h < neighbor.y + neighbor.h) {
newHeight = Math.max(1, neighbor.h + heightChange);
}
}
newHeight = Math.max(1, newHeight);
newHeight = Math.min(newHeight, this.numRows - neighbor.y);
neighbor.h = newHeight;
ids.push(neighbor.i);
this.handleHeightChange(neighbor, heightChange, ids);
}
});
},
layout 数据是响应式,修改了相邻元素的属性,布局也随之发生改变。
扩展
官网,还有很多例子:
jbaysolutions.github.io/vue-grid-la...
如果,官网的属性,方法和例子,还不足以满足你的需求。
那么,可以去 github
下载 vue-grid-layout
的源码
按照自己的需求修改之后,重新打包
arduino
npm run build-lib
在dist文件中生成
vue-grid-layout.umd.js
vue-grid-layout.umd.min.js
然后,在自己项目中引入即可。
比如说,想要 GridItem
支持重叠堆放,可以修改 helpers/utils.js
里面方法
compact
和 moveElement
这两个方法。
最后的话
以上,如果对你有用的话,不妨点赞收藏关注一下,谢谢 🙏
😊 微信公众号: OrzR3
💖 不定期更新一些技术类,生活类,读书类的文章。