从 v1 迁移
本页列出 Grid Layout Plus 从 v1 升级到 v2 时需要处理的不兼容变化,内容以最新的 v1 版本 v1.1.1 为基线。按项目用到的功能阅读相应章节即可。
Layout 改为受控模型
这项变化影响依赖 GridLayout 原地修改 Layout 数组的项目。
v1 会直接修改传入的 Layout 数组和栅格项。v2 把它视为只读输入:GridLayout 会发出新的 Layout,父组件写回后才会提交变更。
使用可写 ref 和 v-model:layout 保存布局:
<script setup lang="ts">
import { ref } from 'vue'
import type { Layout } from 'grid-layout-plus'
const layout = ref<Layout>([
{ i: 'summary', x: 0, y: 0, w: 2, h: 2 }
])
</script>
<template>
<GridLayout v-model:layout="layout" />
</template>已经使用这种写法的项目无需修改。只传 :layout 而不处理 update:layout 仍能只读渲染,但拖拽、缩放和调用组件方法产生的变更不会保留。
必须保持数组引用不变时,请在 update:layout 监听器中原位替换数组内容。参见布局数据。
常规变化
压缩和定位属性
这项变化只影响显式设置过 vertical-compact、use-css-transforms 或 transform-scale 的项目。
v2 用压缩器和定位策略取代这三个属性:
| v1 属性 | v2 替代方式 |
|---|---|
:vertical-compact="true" | :compactor="verticalCompactor"(默认) |
:vertical-compact="false" | :compactor="noCompactor" |
:use-css-transforms="true" | :position-strategy="transformStrategy"(默认) |
:use-css-transforms="false" | :position-strategy="absoluteStrategy" |
:transform-scale="scale" | :position-strategy="scaledStrategy(scale)" |
默认行为仍是垂直压缩和 CSS transform 定位。原来显式传入 true 的项目可以直接删除对应属性;原来关闭压缩、关闭 transform 定位或设置过缩放值的项目需要改用表中的替代方式。
内置实现及其导入方式见 compactor 和 position-strategy。
GridItem 的数据来源
这项变化只影响通过默认插槽手动渲染 GridItem 的项目。使用 item 插槽的项目无需修改。
在 v1 中,项目通常还会把坐标、尺寸和约束传给 GridItem。v2 只把 GridItem.i 用作注册键;几何信息、static、min/max 约束、isDraggable、isResizable 和 zIndex 全部从父级 Layout 中 i 相同的 LayoutItem 读取。
<GridItem
v-for="item in layout"
:key="item.i"
:i="item.i"
>
{{ item.i }}
</GridItem>这些镜像属性为了兼容旧代码仍保留在 GridItemProps 中,但已标记为废弃;GridItem 注册到有效的父级布局后,它们不会覆盖对应的 LayoutItem。isBounded、拖拽和缩放选择器、preserveAspectRatio、interact 选项以及 dragThreshold 仍属于 GridItem。
Layout 校验
这项变化影响包含 v1 接受、但 v2 会拒绝的坐标、尺寸、i 或约束值的布局。
v2 要求坐标和尺寸为 JavaScript 安全整数,坐标不能为负,尺寸必须为正。i 必须唯一,且必须是非空字符串或不是 -0 的安全整数;min/max 关系也必须有效。
初始 Layout 或配置无效时会同步抛出 GridLayoutValidationError。后续收到无效属性时会触发 error 事件,并保留上一次有效的 Layout。调用公开方法时,如果参数无效,会返回 status 为 'rejected' 的结果。不要依赖具体的错误消息文本,请读取错误对象的 code、path 和 cause。
Layout 事件
这项变化只影响会修改事件参数,或依赖事件触发时机的监听器。
v2 的 Layout 事件参数是彼此独立的只读快照。update:layout、layout-updated 和 breakpoint-changed 还会提供包含 revision 与 source 的 LayoutUpdateMeta。只读取 v1 原有参数的监听器可以保持不变。
layout-updated 只会在交互、组件方法调用或外部替换完成提交后触发。更新被拒绝、取消,或父组件没有写回时,不会触发该事件。参见事件。
restoreOnDrag 行为
这项变化只影响显式设置 restore-on-drag="true" 的项目。
默认值仍是 false。设为 true 时,v2 会在拖拽期间把当前栅格项保留在指针所在的候选位置;松开指针后的最终压缩仍可能移动它。升级后应重新检查占位符和最终落点。
已移除的 API
GridLayout 组件引用的内部字段
这项变化只影响直接访问 GridLayout 组件引用的项目。
v1 暴露的 state、getItem()、dragEvent()、resizeEvent() 和 layoutUpdate() 已被移除。v2 的组件引用只暴露 root 以及 setLayout()、moveItem()、resizeItem()、addItem()、removeItem()、bringToFront() 和 sendToBack()。
读取当前状态时,改用受控 Layout 和组件事件。单次修改可以调用对应方法;自定义连续拖拽或缩放流程时,使用 useGridLayout 返回的交互 API。
v1 根入口导出的 LayoutInstance 标记为 @internal,v2 不再导出。组件引用使用 GridLayoutExpose,无头状态使用 UseGridLayoutReturn。
已废弃的 API
以下 API 在 v2 中仍可使用,但会在后续版本移除:
prevent-collision:改用collision-mode="prevent"。Breakpoint:改用DefaultBreakpoint,或为响应式 API 提供自定义断点泛型。ResponsiveLayout:根据用途改用ResponsiveLayoutsInput或CompleteResponsiveLayouts。moveElement:仅依赖旧行为的调用可以继续保留;如果还需要处理边界、碰撞模式和压缩,改用normalizeLayout或useGridLayout。
高级
以下变化只涉及较少见的接入方式。
响应式 Layout
响应式模式下,v2 发出的当前 Layout 和完整断点布局使用同一个 revision。需要持久化响应式布局时,请同时绑定两个 v-model,并在同一轮 Vue 更新中写回:
<GridLayout
v-model:layout="layout"
v-model:responsive-layouts="responsiveLayouts"
responsive
/>手动 GridItem 的 DOM 边界
手动渲染的 GridItem 必须位于所属 GridLayout 的根节点内,并直接使用该根节点作为 CSS 包含块(offsetParent)。
如果 v1 项目使用 Teleport 将栅格项移到根节点外,或在两者之间加入带定位的包装节点,请调整 DOM 结构。v2 会拒绝这类注册,避免继续基于错误的包含块计算几何和处理指针交互。
直接导入布局辅助函数
v1 没有从包根入口公开布局算法,es/helpers/* 和 lib/helpers/* 也不是稳定的 API 入口。如果项目从这些路径导入了 v2 仍支持的布局辅助函数,请改用包根入口或 grid-layout-plus/core:
import { compact, normalizeLayout } from 'grid-layout-plus/core'v2 中稳定的核心函数不会修改输入 Layout,必须使用返回的新 Layout:
layout.value = normalizeLayout(layout.value, {
cols: 12,
maxRows: 40,
collisionMode: 'push',
})compact 的第三个参数现在是 ReadonlyMap,不再接受 v1 的普通对象。数字和字符串形式的 i 会分别处理:
const minPositions = new Map([
[1, { y: 0 }],
['1', { y: 2 }],
])
layout.value = compact(layout.value, false, minPositions)LayoutItem 附加数据
这项变化影响在 LayoutItem 上保存自定义数据的项目。附加值必须是可安全克隆的普通数据;v2 会拒绝函数、类实例、Symbol、循环引用、访问器属性和非有限数值。
请把这些不可克隆的值移到以 i 为键的外部映射中,LayoutItem 只保留普通数据。
从更早的 v1 版本迁移
先查看 CHANGELOG 中从当前版本到 v1.1.1 的变化,再按照本页迁移到 v2。