所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

低代码时代必备!grid-layout-plus 让拖拽布局变得如此简单

还在为复杂的页面布局而头疼吗?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 主要属性

属性类型默认值说明
layoutArray[]布局数据数组
col-numNumber12网格列数
row-heightNumber150行高(像素)
is-draggableBooleantrue是否可拖拽
is-resizableBooleantrue是否可缩放
is-mirroredBooleanfalse是否镜像布局
vertical-compactBooleantrue是否垂直紧凑
marginArray[10, 10]边距 [x, y]
use-css-transformsBooleantrue使用 CSS 变换

GridItem 主要属性

属性类型说明
xNumber水平位置
yNumber垂直位置
wNumber宽度
hNumber高度
iString唯一标识
minWNumber最小宽度
maxWNumber最大宽度
minHNumber最小高度
maxHNumber最大高度
staticBoolean是否静态

实际应用场景

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

评论0

显示验证码
没有账号?注册  忘记密码?