You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用React还原react-grid-layout布局 实现跨框架复用

原生复现react-grid-layout布局效果方案

react-grid-layout的核心实现依赖CSS Grid布局+原生事件监听,完全可以脱离React框架实现,跨框架复用时只需要共享布局状态数组即可。

核心实现步骤

  • 布局层:用CSS Grid作为基础布局方案,提前定义全局统一的列数、行高、网格间隙参数,所有卡片的位置、宽高都和网格线严格对齐,和react-grid-layout的对齐逻辑完全一致
  • 交互层:用原生mousedown/mousemove/mouseup事件组合实现拖拽、resize功能,不需要引入任何第三方依赖:
    • 拖拽触发时记录当前卡片的初始位置、鼠标初始坐标,全局绑定移动、抬起事件
    • 鼠标移动时实时计算偏移量,换算为网格单位的坐标增量,更新卡片位置
    • 鼠标抬起时解绑全局事件,更新全局布局状态
  • 碰撞处理:卡片位置、尺寸变更时遍历所有卡片,检测是否出现重叠,按照“下方元素自动下压”的逻辑调整其他卡片位置,和react-grid-layout的默认压缩行为对齐
  • 状态层:将所有卡片的id、x坐标、y坐标、宽度w、高度h存储为纯JSON数组,该数组和框架完全无关,可以在React、Angular、Vue等任意框架中直接读取渲染

最简实现代码示例

HTML结构

<div class="grid-container">
  <div class="grid-item" data-id="item1" data-x="0" data-y="0" data-w="2" data-h="2">
    卡片1
    <div class="resize-handle"></div>
  </div>
  <div class="grid-item" data-id="item2" data-x="2" data-y="0" data-w="1" data-h="1">
    卡片2
    <div class="resize-handle"></div>
  </div>
</div>

CSS样式

/* 网格容器基础样式 */
.grid-container {
  display: grid;
  grid-template-columns: repeat(12, 1fr); /* 12列网格,可自定义列数 */
  grid-auto-rows: 80px; /* 单行高度,可自定义 */
  gap: 16px; /* 网格间隙,可自定义 */
  padding: 16px;
}
/* 网格卡片样式 */
.grid-item {
  position: relative;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  padding: 12px;
  cursor: move;
  user-select: none;
}
/* resize触发柄样式 */
.resize-handle {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 14px;
  height: 14px;
  background: #3b82f6;
  border-radius: 2px;
  cursor: se-resize;
}

核心JS逻辑

// 全局配置,和CSS参数保持一致即可
const GRID_CONFIG = {
  colCount: 12,
  rowHeight: 80,
  gap: 16
}

const container = document.querySelector('.grid-container')
// 全局布局状态,纯JSON数组,可跨框架复用
let layout = Array.from(document.querySelectorAll('.grid-item')).map(el => ({
  id: el.dataset.id,
  x: parseInt(el.dataset.x),
  y: parseInt(el.dataset.y),
  w: parseInt(el.dataset.w),
  h: parseInt(el.dataset.h)
}))

// 布局渲染函数,根据layout数组更新所有卡片的网格属性
function renderLayout() {
  layout.forEach(item => {
    const el = document.querySelector(`[data-id="${item.id}"]`)
    el.style.gridColumnStart = item.x + 1
    el.style.gridColumnEnd = item.x + item.w + 1
    el.style.gridRowStart = item.y + 1
    el.style.gridRowEnd = item.y + item.h + 1
  })
}

// 初始化渲染布局
renderLayout()

// 后续可补充拖拽、resize、碰撞检测的事件逻辑,均为原生JS实现,无框架依赖

跨框架适配方法

在Angular等其他框架中使用时,只需要把上述layout数组存储为框架的响应式状态,渲染时将对应x/y/w/h的值绑定到元素的grid-column/grid-row相关属性上即可,拖拽、resize的原生事件逻辑不需要修改,直接引入即可生效。

内容的提问来源于stack exchange,提问作者Albert Gao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:36:02