还在为复杂的页面布局而头疼吗?Grid Layout Plus 来拯救你!这是一个专为 Vue 3 设计的可拖拽、可缩放的网格布局系统,让你的页面布局变得像搭积木一样简单!
什么是 Grid Layout Plus?
Grid Layout Plus 是一个强大的 Vue 3 网格布局组件库,它让你可以:
- ️拖拽元素:像移动桌面图标一样自由拖拽
- 缩放元素:随意调整元素大小
- 响应式布局:自动适配不同屏幕尺寸
- 灵活配置:支持各种自定义设置
想象一下,你可以像在手机桌面上整理应用图标一样来设计你的网页布局!
快速开始
安装
选择你喜欢的包管理器:
# 推荐使用 pnpm
pnpm i grid-layout-plus
# 或者使用 yarn
yarn add grid-layout-plus
# 或者使用 npm
npm install grid-layout-plus
基础使用
<template>
<GridLayout v-model:layout="layout" :row-height="30" class="grid-layout">
</GridLayout>
</template>
<script setup>
import { reactive } from "vue";
import { GridLayout } from "grid-layout-plus";
const layout = reactive([
{ x: 0, y: 0, w: 2, h: 2, i: "0", static: false },
{ x: 2, y: 0, w: 2, h: 4, i: "1", static: true },
{ x: 4, y: 0, w: 2, h: 5, i: "2", static: false },
{ x: 6, y: 0, w: 2, h: 3, i: "3", static: false },
{ x: 8, y: 0, w: 2, h: 3, i: "4", static: false },
{ x: 10, y: 0, w: 2, h: 3, i: "5", static: false },
{ x: 0, y: 5, w: 2, h: 5, i: "6", static: false },
{ x: 2, y: 5, w: 2, h: 5, i: "7", static: false },
{ x: 4, y: 5, w: 2, h: 5, i: "8", static: false },
]);
</script>
<style scoped>
:deep(.vgl-layout) {
background: transparent;
border-radius: 8px;
}
:deep(.vgl-item:not(.vgl-item--placeholder)) {
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
border: none;
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
cursor: move;
}
/* 为不同位置的卡片添加不同的渐变色 */
:deep(.vgl-item:nth-child(1)) {
background: linear-gradient(135deg, #ff6b6b, #ee5a24);
}
:deep(.vgl-item:nth-child(2)) {
background: linear-gradient(135deg, #74b9ff, #0984e3);
}
:deep(.vgl-item:nth-child(3)) {
background: linear-gradient(135deg, #00b894, #00a085);
}
:deep(.vgl-item:nth-child(4)) {
background: linear-gradient(135deg, #fdcb6e, #e17055);
}
:deep(.vgl-item:nth-child(5)) {
background: linear-gradient(135deg, #a29bfe, #6c5ce7);
}
:deep(.vgl-item:nth-child(6)) {
background: linear-gradient(135deg, #fd79a8, #e84393);
}
:deep(.vgl-item:nth-child(7)) {
background: linear-gradient(135deg, #fdcb6e, #e17055);
}
:deep(.vgl-item:nth-child(8)) {
background: linear-gradient(135deg, #00b894, #00a085);
}
</style>

核心概念解析
布局数据结构
每个布局项都有以下属性:
{
x: 0, // 水平位置(从0开始)
y: 0, // 垂直位置(从0开始)
w: 6, // 宽度(占用的列数)
h: 4, // 高度(占用的行数)
i: '0', // 唯一标识符
minW: 2, // 最小宽度(可选)
maxW: 12, // 最大宽度(可选)
minH: 2, // 最小高度(可选)
maxH: 8, // 最大高度(可选)
static: false // 是否静态(不可拖拽,可选)
}
网格系统
Grid Layout Plus 使用网格系统来管理布局:
- 列数(col-num):定义网格有多少列,默认 12 列
- 行高(row-height):每行的高度,单位是像素
- 边距(margin):元素之间的间距,格式为
[水平间距, 垂直间距]
常用配置选项
GridLayout 主要属性
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
layout | Array | [] | 布局数据数组 |
col-num | Number | 12 | 网格列数 |
row-height | Number | 150 | 行高(像素) |
is-draggable | Boolean | true | 是否可拖拽 |
is-resizable | Boolean | true | 是否可缩放 |
is-mirrored | Boolean | false | 是否镜像布局 |
vertical-compact | Boolean | true | 是否垂直紧凑 |
margin | Array | [10, 10] | 边距 [x, y] |
use-css-transforms | Boolean | true | 使用 CSS 变换 |
GridItem 主要属性
属性 | 类型 | 说明 |
---|---|---|
x | Number | 水平位置 |
y | Number | 垂直位置 |
w | Number | 宽度 |
h | Number | 高度 |
i | String | 唯一标识 |
minW | Number | 最小宽度 |
maxW | Number | 最大宽度 |
minH | Number | 最小高度 |
maxH | Number | 最大高度 |
static | Boolean | 是否静态 |
实际应用场景
1. 仪表板布局
<template>
<GridLayout
:layout="dashboardLayout"
:col-num="24"
:row-height="50"
:margin="[8, 8]"
>
<GridItem v-for="widget in dashboardLayout" :key="widget.i" v-bind="widget">
<component :is="widget.component" :data="widget.data" />
</GridItem>
</GridLayout>
</template>
2. 内容管理系统
<template>
<div class="cms-layout">
<GridLayout
:layout="contentLayout"
:col-num="16"
:row-height="80"
:is-draggable="editMode"
:is-resizable="editMode"
>
<GridItem v-for="block in contentLayout" :key="block.i" v-bind="block">
<div class="content-block">
<div v-if="editMode" class="edit-controls">
<button @click="editBlock(block)">编辑</button>
<button @click="deleteBlock(block)">删除</button>
</div>
<component :is="block.type" :props="block.props" />
</div>
</GridItem>
</GridLayout>
</div>
</template>
3. 响应式布局
<template>
<GridLayout
:layout="responsiveLayout"
:col-num="getColNum()"
:row-height="getRowHeight()"
:margin="getMargin()"
>
<GridItem v-for="item in responsiveLayout" :key="item.i" v-bind="item">
<div class="responsive-item">
{{ item.content }}
</div>
</GridItem>
</GridLayout>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted } from "vue";
const windowWidth = ref(window.innerWidth);
const getColNum = () => {
if (windowWidth.value < 768) return 4;
if (windowWidth.value < 1024) return 8;
return 12;
};
const getRowHeight = () => {
if (windowWidth.value < 768) return 60;
return 80;
};
const getMargin = () => {
if (windowWidth.value < 768) return [5, 5];
return [10, 10];
};
const handleResize = () => {
windowWidth.value = window.innerWidth;
};
onMounted(() => {
window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
</script>
样式定制
自定义拖拽手柄
.vue-grid-item .vue-resizable-handle {
background: #007bff;
border-radius: 50%;
width: 12px;
height: 12px;
}
.vue-grid-item .vue-resizable-handle:hover {
background: #0056b3;
}
自定义占位符
.vue-grid-placeholder {
background: rgba(0, 123, 255, 0.2);
border: 2px dashed #007bff;
border-radius: 8px;
}
拖拽时的样式
.vue-grid-item.vue-draggable-dragging {
opacity: 0.8;
transform: rotate(5deg);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
常见问题解决
1. 元素重叠问题
// 确保每个元素都有唯一的 i 值
const layout = [
{ x: 0, y: 0, w: 6, h: 4, i: "unique-id-1" },
{ x: 6, y: 0, w: 6, h: 4, i: "unique-id-2" },
];
2. 响应式问题
// 使用计算属性处理响应式布局
const responsiveLayout = computed(() => {
return layout.value.map((item) => ({
...item,
w: windowWidth.value < 768 ? Math.min(item.w, 4) : item.w,
}));
});
3. 性能优化
// 使用 v-memo 优化大量元素
<GridItem
v-for="item in layout"
:key="item.i"
v-memo="[item.x, item.y, item.w, item.h]"
v-bind="item"
>
<div class="item">{{ item.content }}</div>
</GridItem>
总结
Grid Layout Plus 是一个功能强大且易于使用的 Vue 3 网格布局库。它让复杂的页面布局变得简单直观,就像在桌面上整理图标一样轻松。
主要优势:
- ✅ 简单易用:API 设计直观,学习成本低
- ✅ 功能丰富:支持拖拽、缩放、响应式等
- ✅ 高度可定制:支持各种样式和配置
- ✅ 性能优秀:基于 Vue 3 的响应式系统
- ✅ 社区活跃:持续更新和维护
适用场景:
- 数据仪表板
- 内容管理系统
- 移动端应用
- ️ 桌面应用
- 游戏界面
现在就开始使用 Grid Layout Plus,让你的页面布局变得更加灵活和美观吧!
** 小贴士**:如果你觉得这篇文章对你有帮助,别忘了点赞和分享哦!有问题欢迎在评论区讨论~
** 相关链接**:
官方文档:https://grid-layout-plus.netlify.app/
GitHub 仓库:https://github.com/qmhc/grid-layout-plus
原文链接:https://code.ifrontend.net/archives/1357,转载请注明出处。
评论0