拖拽宫格vue-grid-layout详细应用及案例
1、前言
vue-grid-layout是一个适用于vue的拖拽栅格布局库,功能齐全,适用于拖拽+高度/宽度自由调节的布局需求。本文将讲述一些常用参数和事件,以及做一个同步拖拽的Demo。效果动态图如下:

2、安装
- vue2版本:
npm install vue-grid-layout --save
- vue3版本:
npm install vue-grid-layout@3.0.0-beta1 --save
3、属性
- GridLayout 容器:
| 属性名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| layout | Array | 是 | - | 数据源,每一项必须有i, x, y, w 和 h属性 |
| colNum | Int | 否 | 12 | 列数 |
| rowHeight | Int | 否 | 150 | 每行的高度像素 |
| maxRows | Int | 否 | Infinity | 最大行数 |
| margin | Array | 是 | [10, 10] | 元素边距 |
| isDraggable | Boolean | 否 | true | 是否可拖拽 |
| isResizable | Boolean | 否 | true | 是否可调整大小 |
| isMirrored | Boolean | 否 | false | 是否可镜像反转 |
| autoSize | Boolean | 否 | true | 是否自动调整大小 |
| verticalCompact | Boolean | 否 | true | 布局是否垂直压缩 |
| preventCollision | Boolean | 否 | false | 防止碰撞,为true则元素只能拖动至空白处 |
| useCssTransforms | Boolean | 否 | true | 是否使用CSS属性 transition-property: transform |
| responsive | Boolean | 否 | false | 布局是否为响应式 |
| breakpoints | Boolean | 否 | 为响应式布局设置断点 | |
| cols | Boolean | 否 | 设置每个断点对应的列数 |
- GridItem 子项:
| 属性名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| i | string | 是 | - | 子项ID |
| x | number | 是 | - | 元素位于第几列 |
| y | number | 是 | - | 元素位于第几行 |
| w | number | 是 | - | 初始宽度,值必须为colNum的倍数 |
| h | number | 是 | - | 初始高度,值必须为rowHeight的倍数 |
| minW | number | 否 | 1 | 元素最小宽度,值必须为colNum的倍数,如果w小于minW,则minW的值会被w覆盖 |
| minH | number | 否 | 1 | 元素最小高度,值必须为rowHeight的倍数,如果h小于minH,则minH的值会被h覆盖 |
| maxW | number | 否 | Infinity | 元素最大宽度,值必须为colNum的倍数,如果w大于maxW,则maxW的值会被w覆盖 |
| maxH | number | 否 | Infinity | 元素最大高度,值必须为rowHeight的倍数,如果h大于maxH,则maxH的值会被h覆盖 |
| isDraggable | Boolean | 否 | null | 是否可拖拽。如果值为null则取决于父容器 |
| isResizable | Boolean | 否 | null | 是否可调整大小。如果值为null则取决于父容器 |
| static | Boolean | 否 | false | 是否为静态的,无法拖拽、调整大小或被其他元素移动 |
| dragIgnoreFrom | string | 否 | 'a, button' | 标识哪些子元素无法触发拖拽事件,值为css-like选择器 |
| dragAllowFrom | string | 否 | null | 标识哪些子元素可以触发拖拽事件,值为css-like选择器,如果值为null则表示所有子元素 |
| resizeIgnoreFrom | string | 否 | 'a, button' | 标识哪些子元素无法触发调整大小的事件,值为css-like选择器 |
4、事件
- GridLayout 容器:
| 事件名 | 描述 |
|---|---|
| layoutCreatedEvent | 对应Vue生命周期的created |
| layoutBeforeMountEvent | 对应Vue生命周期的beforeMount |
| layoutMountedEvent | 对应Vue生命周期的mounted |
| layoutReadyEvent | 当完成mount中的所有操作时生成的事件 |
| layoutUpdatedEvent | 布局更新或栅格元素的位置重新计算事件 |
| breakpointChangedEvent | 断点更改事件,每次断点值由于窗口调整大小而改变 |
- GridItem 子项:
| 事件名 | 描述 |
|---|---|
| moveEvent | 移动时的事件 |
| resizeEvent | 调整大小时的事件 |
| movedEvent | 移动后的事件 |
| resizedEvent | 调整大小后的事件 |
| containerResizedEvent | 栅格元素/栅格容器更改大小的事件(浏览器窗口或其他) |
5、占位符样式修改
直接覆盖默认的class样式
.vue-grid-item.vue-grid-placeholder {
background: red;
opacity: 0.2;
transition-duration: 100ms;
z-index: 2;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.vue-grid-item.vue-grid-placeholder {
background: green !important;
}
6、案例
注:本案例是按照vue3的写法
- HTML:
<div class="grid_box">
<div class="left">
<grid-layout
v-model:layout="layoutLeft"
:col-num="4"
:row-height="50"
:is-draggable="true"
:is-resizable="true"
:is-mirrored="false"
:vertical-compact="true"
:margin="[10, 10]"
:use-css-transforms="true"
ref="gridLeftRef"
>
<grid-item
v-for="item in layoutLeft"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
@resized="handleGridSync"
@moved="handleGridSync"
>
<div class="left_layout_item">
<div class="del_btn" @click="deleteGrid(item.i)">删</div>
<span>{{ item.i }}</span>
</div>
</grid-item>
</grid-layout>
</div>
<div class="right">
<grid-layout
v-model:layout="layoutRight"
:col-num="4"
:row-height="10"
:is-draggable="true"
:is-resizable="true"
:is-mirrored="false"
:vertical-compact="true"
:margin="[10, 10]"
:use-css-transforms="true"
ref="gridRightRef"
>
<grid-item v-for="item in layoutRight" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" :key="item.i">
<div class="right_layout_item">{{ item.i }}</div>
</grid-item>
</grid-layout>
</div>
</div>
- 引入组件
import VueGridLayout from 'vue-grid-layout'
- 数据源:
const gridLeftRef = ref<any>()
const gridRightRef = ref<any>()
const layoutLeft = ref([
{ i: '1', x: 0, y: 0, w: 2, h: 2 },
{ i: '2', x: 2, y: 0, w: 2, h: 2 },
{ i: '3', x: 0, y: 0, w: 2, h: 2 },
{ i: '4', x: 2, y: 0, w: 2, h: 2 }
])
const layoutRight = ref([
{ i: '1', x: 0, y: 0, w: 2, h: 2 },
{ i: '2', x: 2, y: 0, w: 2, h: 2 },
{ i: '3', x: 0, y: 0, w: 2, h: 2 },
{ i: '4', x: 2, y: 0, w: 2, h: 2 }
])
- 处理方法:
// 处理Grid同步
const handleGridSync = () => {
layoutLeft.value.forEach((item1) => {
layoutRight.value.forEach((item2) => {
if (item1.i === item2.i) {
item2.x = item1.x
item2.y = item1.y
item2.w = item1.w
item2.h = 2
}
})
})
gridLeftRef.value.layoutUpdate()
gridLeftRef.value.updateHeight()
gridRightRef.value.layoutUpdate()
gridRightRef.value.updateHeight()
}
// 创造Grid
const createGrid = () => {
let maxH = 0
layoutLeft.value.forEach((item) => {
if (item.y > maxH) maxH = item.y
})
const uid = createUuid()
layoutLeft.value.push({ i: uid, x: 0, y: maxH, w: 2, h: 2 })
layoutRight.value.push({ i: uid, x: 0, y: maxH, w: 2, h: 2 })
handleGridSync()
}
// 删除Grid
const deleteGrid = (id: string) => {
const idx1 = layoutLeft.value.findIndex((item1) => item1.i === id)
layoutLeft.value.splice(idx1, 1)
const idx2 = layoutRight.value.findIndex((item2) => item2.i === id)
layoutRight.value.splice(idx2, 1)
handleGridSync()
}
本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~
PS:在本页按F12,在console中输入document.querySelectorAll('.diggit')[0].click(),有惊喜哦

公众号
往期文章
- Vue2全家桶+Element搭建的PC端在线音乐网站
- 超详细的Cookie增删改查
- 助你上手Vue3全家桶之Vue-Router4教程
- 助你上手Vue3全家桶之Vue3教程
- 助你上手Vue3全家桶之VueX4教程
- 使用nvm管理node.js版本以及更换npm淘宝镜像源
- 超详细!Vue-Router手把手教程
- 超详细!Vue的九种通信方式
- 超详细!Vuex手把手教程
个人主页
拖拽宫格vue-grid-layout详细应用及案例的更多相关文章
- 拖拽方式生成Vue用户界面
前一阵子拜访了一些小伙伴,大家都表示苦前端太久了,需要花费不少时间在前端开发上.本着在不损失灵活性的前提下尽可能提高开发效率的原则,作者尝试在框架内集成了拖拽方式生成Vue用户界面的功能作为补充, ...
- gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
前言 Excel功能强大,应用广泛.随着web应用的兴起和完善,用户的要求也越来越高.很多Excel的功能都搬到了sass里面.恨不得给他们做个Excel出来...程序员太难了... 去年我遇到了 ...
- 可拖拽排序的vue组件
最近在优化一个vue的博客系统,想实现文章列表处的文章拖拽功能.就试了一下awe-dnd vue插件,觉得还挺好用的. 安装 npm install awe-dnd --save 使用 在main.j ...
- QT之——QTableWidget拖拽单元格并替换内容(进阶)
所需待重写函数: [virtual] bool QObject::eventFilter(QObject *watched, QEvent *event); /* * Filters events i ...
- Vue-Grid-Layout分享一款好用的可拖拽组件
在使用Grafana的过程中,发现Grafana关于视图页面中每一个面板都可拖拽,可随意放大放小,体验非常棒,F12看了Grafana的代码,看打包后的代码很像react,进一步css,看到有grid ...
- 基于Vue实现可以拖拽的树形表格(原创)
因业务需求,需要一个树形表格,并且支持拖拽排序,任意未知插入,github搜了下,真不到合适的,大部分树形表格都没有拖拽功能,所以决定自己实现一个.这里分享一下实现过程,项目源代码请看github,插 ...
- vue下使用echarts折线图及其横坐标拖拽功能
vue页面中使用折线图,并且有时间段筛选.因此就需要用到横坐标的拖拽功能. 界面效果如下: 现在来看这个效果的实现代码: drawLine() { let that = this, lineDate ...
- Vue.Draggable实现拖拽效果(采坑小记)
之前有写过Vue.Draggable实现拖拽效果(快速使用)(http://www.cnblogs.com/songdongdong/p/6928945.html)最近项目中要用到这个拖拽的效果,当产 ...
- 基于Vue实现拖拽效果
参考地址:基于Vue实现拖拽效果 参考链接中讲的比较详细,我只使用了其中自定义指令的方法.整体代码如下: <template> <!-- 卡片 --> <div clas ...
- vue2-dragula vue拖拽组件
https://github.com/kristianmandrup/vue2-dragula git 地址 https://github.com/kristianmandrup/vue2-dragu ...
随机推荐
- 2022-03-22:二进制取反。 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0。那么取反之后的num可能的最大的字典序是多少呢。如有
2022-03-22:二进制取反. 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0.那么取反之后的num可能的最大的字典序是多少呢.如有 ...
- openstack部署2
检查服务,查看dashboard页面有哪些功能 检查服务状态 检查计算节点,控制节点服务是up状态 检查网络节点是True的状态.这里的每个计算节点,都是一个neutron的客户端. 查看dashbo ...
- C++中的字符串编码处理
今天由于在项目中用到一些与C++混合开发的东西 ,需要通过socket与C++那边交换数据,没啥特别的,字节码而已,两边确定一种编码规则就行了.我们确定的UTF-8.关于C++的 这种又是宽字节 又是 ...
- React-hooks 父组件通过ref获取子组件数据和方法
我们知道,对于子组件或者节点,如果是class类,存在实例,可以通过 React.createRef() 挂载到节点或者组件上,然后通过 this 获取到该节点或组件. class RefTest e ...
- gitlab-runner 中的 Docker-in-Docker
笔者个人理解:gitlab-runner 安装后就是一个监听状态的 runner,而通过 gitlab-runner register 注册的"实例"其实只是预定义的配置节,当消息 ...
- Luogu1772 [ZJOI2006] 物流运输
传送门 简化题意 给你 \(m\) 个码头,码头之间有双向边连接,\(n\) 天,其中一些码头在某些天会不可用,这 \(n\) 天都要有一条从 \(1\) 到 \(m\) 的路,每一次更换道路会需要 ...
- 欢迎来到farter的可能是最后一个用于博客的地方【
目前先把公告栏里放一堆链接作为导航了(手机上竟然没有公告栏??? 准备从新浪博客往这里迁,整活可能也在这里? 还是复制一份公告栏的链接库吧( 歌声合成相关文章 敝个人站(好用好玩都在这) 敝渣浪博客( ...
- linux nfs共享存储服务
目录 一.nfs服务 二.nfs优点 三.配置文件 四.共享文件配置过程 五.实验 1.创建共享文件(两台终端共享) 一.nfs服务 概念:网络上共享文件系统的协议,运行多个服务器之间通过网络共享文件 ...
- Python基础 - 标识符命名规范
标识符是什么? 标识符主要用来给变量名,函数名,方法名,类名起名时要遵循的规范 硬性规则 见名知意(使用中文转译后的英文) 由字母,数字,下划线组成, 并且不能以数字开头, 不能和Python关 ...
- 编码器 | 基于 Transformers 的编码器-解码器模型
基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶.本文简要介绍了神经编码器-解码器模型的历史,更多背景知识,建议读者阅读由 Sebastion ...