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(),有惊喜哦


公众号

往期文章

个人主页

拖拽宫格vue-grid-layout详细应用及案例的更多相关文章

  1. 拖拽方式生成Vue用户界面

      前一阵子拜访了一些小伙伴,大家都表示苦前端太久了,需要花费不少时间在前端开发上.本着在不损失灵活性的前提下尽可能提高开发效率的原则,作者尝试在框架内集成了拖拽方式生成Vue用户界面的功能作为补充, ...

  2. gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)

    前言   Excel功能强大,应用广泛.随着web应用的兴起和完善,用户的要求也越来越高.很多Excel的功能都搬到了sass里面.恨不得给他们做个Excel出来...程序员太难了... 去年我遇到了 ...

  3. 可拖拽排序的vue组件

    最近在优化一个vue的博客系统,想实现文章列表处的文章拖拽功能.就试了一下awe-dnd vue插件,觉得还挺好用的. 安装 npm install awe-dnd --save 使用 在main.j ...

  4. QT之——QTableWidget拖拽单元格并替换内容(进阶)

    所需待重写函数: [virtual] bool QObject::eventFilter(QObject *watched, QEvent *event); /* * Filters events i ...

  5. Vue-Grid-Layout分享一款好用的可拖拽组件

    在使用Grafana的过程中,发现Grafana关于视图页面中每一个面板都可拖拽,可随意放大放小,体验非常棒,F12看了Grafana的代码,看打包后的代码很像react,进一步css,看到有grid ...

  6. 基于Vue实现可以拖拽的树形表格(原创)

    因业务需求,需要一个树形表格,并且支持拖拽排序,任意未知插入,github搜了下,真不到合适的,大部分树形表格都没有拖拽功能,所以决定自己实现一个.这里分享一下实现过程,项目源代码请看github,插 ...

  7. vue下使用echarts折线图及其横坐标拖拽功能

    vue页面中使用折线图,并且有时间段筛选.因此就需要用到横坐标的拖拽功能. 界面效果如下: 现在来看这个效果的实现代码: drawLine() { let that = this, lineDate ...

  8. Vue.Draggable实现拖拽效果(采坑小记)

    之前有写过Vue.Draggable实现拖拽效果(快速使用)(http://www.cnblogs.com/songdongdong/p/6928945.html)最近项目中要用到这个拖拽的效果,当产 ...

  9. 基于Vue实现拖拽效果

    参考地址:基于Vue实现拖拽效果 参考链接中讲的比较详细,我只使用了其中自定义指令的方法.整体代码如下: <template> <!-- 卡片 --> <div clas ...

  10. vue2-dragula vue拖拽组件

    https://github.com/kristianmandrup/vue2-dragula git 地址 https://github.com/kristianmandrup/vue2-dragu ...

随机推荐

  1. 2022-03-22:二进制取反。 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0。那么取反之后的num可能的最大的字典序是多少呢。如有

    2022-03-22:二进制取反. 有一个二进制字符串,可以选择该串中的任意一段区间进行取反(可以进行一次或不进行),取反指将0变为1,将1变为0.那么取反之后的num可能的最大的字典序是多少呢.如有 ...

  2. openstack部署2

    检查服务,查看dashboard页面有哪些功能 检查服务状态 检查计算节点,控制节点服务是up状态 检查网络节点是True的状态.这里的每个计算节点,都是一个neutron的客户端. 查看dashbo ...

  3. C++中的字符串编码处理

    今天由于在项目中用到一些与C++混合开发的东西 ,需要通过socket与C++那边交换数据,没啥特别的,字节码而已,两边确定一种编码规则就行了.我们确定的UTF-8.关于C++的 这种又是宽字节 又是 ...

  4. React-hooks 父组件通过ref获取子组件数据和方法

    我们知道,对于子组件或者节点,如果是class类,存在实例,可以通过 React.createRef() 挂载到节点或者组件上,然后通过 this 获取到该节点或组件. class RefTest e ...

  5. gitlab-runner 中的 Docker-in-Docker

    笔者个人理解:gitlab-runner 安装后就是一个监听状态的 runner,而通过 gitlab-runner register 注册的"实例"其实只是预定义的配置节,当消息 ...

  6. Luogu1772 [ZJOI2006] 物流运输

    传送门 简化题意 给你 \(m\) 个码头,码头之间有双向边连接,\(n\) 天,其中一些码头在某些天会不可用,这 \(n\) 天都要有一条从 \(1\) 到 \(m\) 的路,每一次更换道路会需要 ...

  7. 欢迎来到farter的可能是最后一个用于博客的地方【

    目前先把公告栏里放一堆链接作为导航了(手机上竟然没有公告栏??? 准备从新浪博客往这里迁,整活可能也在这里? 还是复制一份公告栏的链接库吧( 歌声合成相关文章 敝个人站(好用好玩都在这) 敝渣浪博客( ...

  8. linux nfs共享存储服务

    目录 一.nfs服务 二.nfs优点 三.配置文件 四.共享文件配置过程 五.实验 1.创建共享文件(两台终端共享) 一.nfs服务 概念:网络上共享文件系统的协议,运行多个服务器之间通过网络共享文件 ...

  9. Python基础 - 标识符命名规范

    标识符是什么? 标识符主要用来给变量名,函数名,方法名,类名起名时要遵循的规范 硬性规则   见名知意(使用中文转译后的英文)  由字母,数字,下划线组成, 并且不能以数字开头, 不能和Python关 ...

  10. 编码器 | 基于 Transformers 的编码器-解码器模型

    基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶.本文简要介绍了神经编码器-解码器模型的历史,更多背景知识,建议读者阅读由 Sebastion ...