Vue-grid-layout实现web拖拽布局功能

最近在完成web端在线绘图功能时,需要开发一个从左侧拖拽一种图标到画布中。调研了非常多种现在做拖拽布局的组件,调研的地址是:https://vuejsexamples.com/tag/drag/

该网站提供了非常多的拖拽解决方案

经过比较,选择了一款优秀的可拖拽框架,vue-grid-layout。

npm安装

npm install vue-grid-layout --save

使用demo

<grid-layout
            :layout.sync="layout"
            :col-num="12"
            :row-height="30"
            :is-draggable="true"
            :is-resizable="true"
            :is-mirrored="false"
            :vertical-compact="true"
            :margin="[10, 10]"
            :use-css-transforms="true"
    >

        <grid-item v-for="item in layout"
                   :x="item.x"
                   :y="item.y"
                   :w="item.w"
                   :h="item.h"
                   :i="item.i"
                   :key="item.i">
            {{item.i}}
        </grid-item>
    </grid-layout>
layout: [
                {"x":0,"y":0,"w":2,"h":2,"i":"0"},
                {"x":2,"y":0,"w":2,"h":4,"i":"1"},
                {"x":4,"y":0,"w":2,"h":5,"i":"2"},
                {"x":6,"y":0,"w":2,"h":3,"i":"3"},
            ],

参数说明
layout: 选择组件的列表,Array类型。数组中的每个项目必须有i,x,y,w和h属性。
responsiveLayouts: 响应式布局,非必须。
colNum:指明画布中一共多少列,默认为12列。
rowHeight: 一行所占的高度,单位为像素。
maxRows:最大的行数,默认为无限。
margin:项目的空白值,默认为[10, 10]。
isDraggable: 是否可拖拽。
isResizable: 是否可以变换尺寸。
isMirrored:默认从左到右排序,开启以后从右到左。
autoSize: 根据组件里的内容,自适应高度。
verticalCompact: 垂直方向上是否受影响,如果关闭的话,组件可以有空缺。
preventCollision: 避免碰撞,默认为false。
useCssTransforms
responsive
breakpoints
cols: 总的列数。
useStyleCursor:未知。

griditem的参数

i: 每个组件的唯一id,这个参数是必须的。
x:标识栅格元素位于第几列,需为自然数。
y:标识栅格元素位于第几行,需为自然数。
w:标识栅格元素的初始宽度,值为colWidth的倍数。
h:标识栅格元素的初始高度,值为rowHeight的倍数。
minW:栅格元素的最小宽度,值为colWidth的倍数。如果w小于minW,则minW的值会被w覆盖。
minH:栅格元素的最小高度,值为rowHeight的倍数。如果h小于minH,则minH的值会被h覆盖。
maxW栅格元素的最大宽度,值为colWidth的倍数。
如果w大于maxW,则maxW的值会被w覆盖。
maxH栅格元素的最大高度,值为rowHeight的倍数。
如果h大于maxH,则maxH的值会被h覆盖。
isDraggable:标识栅格元素是否可拖拽。如果值为null则取决于父容器。
isResizable:标识栅格元素是否可调整大小。如果值为null则取决于父容器。
static:标识栅格元素是否为静态的(无法拖拽、调整大小或被其他元素移动)。
dragIgnoreFrom:标识栅格元素中哪些子元素无法触发拖拽事件,值为css-like选择器。
dragAllowFrom:标识栅格元素中哪些子元素可以触发拖拽事件,值为css-like选择器。
如果值为null则表示所有子元素(dragIgnoreFrom的除外)。
resizeIgnoreFrom标识栅格元素中哪些子元素无法触发调整大小的事件,值为css-like选择器。

限制可拖拽区域

如果我们希望可拖拽的组件中,内部是可以单独点击的,那么就需要就拖拽的区域分隔。这里官方提供了参数,可以指定哪些区域是可以拖拽的,哪些区域会被忽略,从而被忽略的区域可以单独进行点击。

 <grid-item v-for="item in layout"
                       :x="item.x"
                       :y="item.y"
                       :w="item.w"
                       :h="item.h"
                       :i="item.i"
                       drag-allow-from=".vue-draggable-handle"
                       drag-ignore-from=".no-drag"
            >
                <div class="text">
                    <div class="vue-draggable-handle"></div>
                    <div class="no-drag">
                        <span>{{item.i}}</span>
                        <br/>
                        <button>click</button>
                    </div>
                </div>
            </grid-item>

限制特定区域可以进行拖拽

从外部拖拽组件到画布中

在我们的应用中希望,组件能够从左侧拖到画布中,而再进行拖拽,所以我们在右侧需要先写一个区域是用来被拖拽的。在备选拖拽区域用两个方法来进行触发。

<div @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"
             unselectable="on">Droppable Element (Drag me!)</div>

具体的代码可以参考官方代码。

<template>
    <div>
        <div>
            <div class="layoutJSON">
                Displayed as <code>[x, y, w, h]</code>:
                <div class="columns">
                    <div class="layoutItem" v-for="item in layout">
                        <b>{{ item.i }}</b>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
                    </div>
                </div>
            </div>
        </div>
        <br/>
        <div @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"
             unselectable="on">Droppable Element (Drag me!)</div>
        <div id="content">
            <grid-layout ref="gridlayout" :layout.sync="layout"
                         :col-num="12"
                         :row-height="30"
                         :is-draggable="true"
                         :is-resizable="true"
                         :vertical-compact="true"
                         :use-css-transforms="true"
            >
                <grid-item :key="item.i" v-for="item in layout"
                           :x="item.x"
                           :y="item.y"
                           :w="item.w"
                           :h="item.h"
                           :i="item.i"
                >
                    <span class="text">{{ item.i }}</span>
                </grid-item>
            </grid-layout>
        </div>
    </div>
</template>

从外部拖拽到画布中

其他更多的官方说明,请参考https://jbaysolutions.github.io/vue-grid-layout/。

该组件是非常强大和灵活的,官方提供的文档也比较全面、易懂。

如果您觉得上面的内容对您有帮助欢迎点赞、评论、转发!
更多内容请查阅作者博客:https://jiaruiblog.com
或者star作者github: https://github.com/Jarrettluo?tab=repositories

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值