vue-grid-layout组件的改装--暴露布局方法

vue-grid-layout是一个非常优秀的vue栅格拖动布局的组件,使用方法请参考官网

属性 GridLayout参数:

layout
类型:Array
必需:true
这是网格的初始布局。
值必须是 Object 项的Array。 每个项目必须有 i,x,y,w 和 h proprties。 有关详细信息,请参阅 GridItem 文档 below。

colNum
类型:Number
必需:false
默认值:12
表示网格有多少列。
这个值应该是一个的自然数。

rowHeight
类型:Number
必需:false
默认值:150
表示单个行的高度以像素为单位。

maxRows
类型:Number
必需:false
默认值:Infinity
表示网格中的最大行数。

margin
类型:Array
必需:false
默认值:[10, 10]
表示网格的元素的边距是多少。
值必须是 Number的两个元素 Array。 每个值都用像素表示。 第一个元素是水平的margin,第二个元素是垂直边。

isDraggable
类型:Boolean
必需:false
默认值:true
表示网格的项是否可以拖动。

isResizable
类型:Boolean
必需:false
默认值:true
表示网格的项是否可以调整大小。

isMirrored
类型:Boolean
必需:false
默认值:false
表示是否应该反转 rtl/ltr。

autoSize
类型:Boolean
必需:false
默认值:true
表示容器高度是否应增大并收缩以适应内容。

verticalCompact
类型:Boolean
必需:false
默认值:true
表示布局是否应垂直为 compact。

useCssTransforms
类型:Boolean
必需:false
默认值:true
表示是否应使用 CSS transition-property: transform,否则是postion定位;。
属性GridItem参数
i
类型:String
必需:true
这是项的唯一标识符。

x
类型:Number
必需:true
表示项( 在哪个列中放置它)的初始水平位置。
值必须是一个整数。

y
类型:Number
必需:true
表示项( 应放置在哪一行)的初始垂直位置。
值必须是一个整数。

w
类型:Number
必需:true
表示项的初始宽度。
值是一个与 colWidth 相乘的数字。

h
类型:Number
必需:true
表示项的初始高度。
值是一个与 rowHeight 相乘的数字。

minW
类型:Number
必需:false
默认值:1
表示项的最小宽度。 如果 w 将小于 minW,那么 w 将被设置为 minW。
值是一个与 colWidth 相乘的数字。

minH
类型:Number
必需:false
默认值:1
表示什么是项的最小 hieght。 如果 h 将小于 minH,那么 h 将被设置为 minH。
值是一个与 rowHeight 相乘的数字。

maxW
类型:Number
必需:false
默认值:Infinity
表示项的最大宽度。 如果 w 大于 maxW,那么 w 将被设置为 maxW。
值是一个与 colWidth 相乘的数字。

maxH
类型:Number
必需:false
默认值:Infinity
表示什么是项的最大高度。 如果 h 大于 maxH,那么 h 将被设置为 maxH。
值是一个与 rowHeight 相乘的数字

isDraggable
类型:Boolean
必需:false
默认值:null
表示项是否可以拖动。
如果默认值为 null,则从父值继承。

isResizable
类型:Boolean
必需:false
默认值:null
表示项是否可以调整大小。
如果默认值为 null,则从父值继承。

dragIgnoreFrom
类型:String
必需:false
默认值:'a, button'
表示项的哪些元素不应触发项的拖动事件。
值为 css-like 选择器字符串。

dragAllowFrom
类型:String
必需:false
默认值:null
表示项的哪些元素应触发项的拖动事件。
值为 css-like 选择器字符串。
如果 null 可以拖动,则可以拖动项的任何( 排除 dragIgnoreFrom ) 元素。

resizeIgnoreFrom
类型:String
必需:false
默认值:'a, button'
表示项的哪些元素不应触发项的大小调整事件。
值为 css-like 选择器字符串。

上面的属性需要注意的是:

  • w宽度时表示占据栅格的数比如: 1/12 2/12 3/12 (12是colNum)
  • 在gridItem里w+x的最大和不应该超过colNum,否则会不生效
  • verticalCompact表示的是垂直紧凑型布局,意思是当每一个gridItem上方没有其>他栅格时,总会向上靠拢
  • useCssTransforms为true时使用c3属性translate3D实现平移,为false是采用的定位实现平移

好了,总结上面的内容:

现在有一个需求,当点击按钮的时候,重新布局页面上的栅格系统:


具体实现思路无非就是重新给gridItem赋值,参数可以自定义,但是要注意到校验参数,w与x的值是不能为小数的,因为他们代表的是栅格数,表现到页面上:

栅格数 * 每一个栅格的宽度

layoutGridItem(){
            //出入的是对象
            // let config = {
            //     i: 0,
            //     sizeObj: {
            //         w: 2,
            //         h: 5
            //     },
            //     positionObj: {
            //         x: 2,
            //         y: 4
            //     }
            // }

            let config = [{
                i: 0,
                sizeObj: {
                    w: 2,
                    h: 5
                },
                positionObj: {
                    x: 2,
                    y: 4
                },
             },{
                i: 2,
                sizeObj: {
                    w: 2,
                    h: 5
                },
                positionObj: {
                    x: 2,
                    y: 4
                }
            }]

            //判断传入的参数是对象,还是数组
            if(Object.prototype.toString.call(config) == "[object Object]") {
                //校验参数
                try{
                   let xString = config.positionObj.x + ""
                   let wString = config.sizeObj.w + ""

                   //判断传入的参数是否是小数 
                   if(xString.includes(".") || wString.includes(".")) {
                        throw new Error("x 与 w参数不能是小数")
                   }

                   //判断x与w的和是否大于栅格数
                   if(config.positionObj.x + config.sizeObj.w > this.colNum) {
                       throw new Error("x 与 w之和不能大于栅格数")
                   }
                }catch(e) {
                    console.log(e)
                    return 
                }

                //设置新的布局格式
                this.verticalCompact = false
                this.layout.forEach(item => {
                    if(item.i == config.i) {
                        item.h = config.sizeObj.h
                        item.w = config.sizeObj.w
                        item.x = config.positionObj.x
                        item.y = config.positionObj.y
                        console.log(item.x,item.y,item.h,item.w)
                    }
                })
            }

            if(Object.prototype.toString.call(config) == "[object Array]") {
                //校验参数
                try{
                   config.forEach(_ => {
                        let xString = _.positionObj.x + ""
                        let wString = _.sizeObj.w + ""

                        //判断传入的参数是否是小数 
                        if(xString.includes(".") || wString.includes(".")) {
                                throw new Error("x 与 w参数不能是小数")
                        }

                        //判断x与w的和是否大于栅格数
                        if(_.positionObj.x + _.sizeObj.w > this.colNum) {
                            throw new Error("x 与 w之和不能大于栅格数")
                        }
                   })
                }
                catch(e) {
                    console.log(e)
                    return 
                }

                this.verticalCompact = false
                this.layout.forEach(item => {
                    config.forEach(_ => {
                        if(item.i == _.i) {
                            item.h = _.sizeObj.h
                            item.w = _.sizeObj.w
                            item.x = _.positionObj.x
                            item.y = _.positionObj.y
                            console.log(item.x,item.y,item.h,item.w)
                        }
                    })
                })
            }
        }

完整源码:

<template>
    <div class="layout">
       <grid-layout
            :layout.sync="layout"
            :col-num="colNum"
            :row-height="30"
            :is-draggable="true"
            :is-resizable="true"
            :vertical-compact="verticalCompact"
            :margin="[10, 10]"
            :use-css-transforms="false"
            class="hoverStyle">
            <grid-item v-for="item in layout" :key="item.i"
                    :x="item.x"
                    :y="item.y"
                    :w="item.w"
                    :h="item.h"
                    :i="item.i"
                    style="border: 1px solid #fff">
                {{item.i}}
            </grid-item>
        </grid-layout> 

        <button @click="layoutGridItem">点击</button>
    </div>
</template>

<script>
import VueGridLayout from 'vue-grid-layout';

export default {
    components: {
        GridLayout: VueGridLayout.GridLayout,
        GridItem: VueGridLayout.GridItem
    },
    data(){
        return {
            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"},
            ],
            verticalCompact: true,
            colNum: 12 //栅格数
        }
    },
    methods: {
        
        layoutGridItem(){
            //出入的是对象
            // let config = {
            //     i: 0,
            //     sizeObj: {
            //         w: 2,
            //         h: 5
            //     },
            //     positionObj: {
            //         x: 2,
            //         y: 4
            //     }
            // }

            let config = [{
                i: 0,
                sizeObj: {
                    w: 2,
                    h: 5
                },
                positionObj: {
                    x: 2,
                    y: 4
                },
             },{
                i: 2,
                sizeObj: {
                    w: 2,
                    h: 5
                },
                positionObj: {
                    x: 2,
                    y: 4
                }
            }]

            //判断传入的参数是对象,还是数组
            if(Object.prototype.toString.call(config) == "[object Object]") {
                //校验参数
                try{
                   let xString = config.positionObj.x + ""
                   let wString = config.sizeObj.w + ""

                   //判断传入的参数是否是小数 
                   if(xString.includes(".") || wString.includes(".")) {
                        throw new Error("x 与 w参数不能是小数")
                   }

                   //判断x与w的和是否大于栅格数
                   if(config.positionObj.x + config.sizeObj.w > this.colNum) {
                       throw new Error("x 与 w之和不能大于栅格数")
                   }
                }catch(e) {
                    console.log(e)
                    return 
                }

                //设置新的布局格式
                this.verticalCompact = false
                this.layout.forEach(item => {
                    if(item.i == config.i) {
                        item.h = config.sizeObj.h
                        item.w = config.sizeObj.w
                        item.x = config.positionObj.x
                        item.y = config.positionObj.y
                        console.log(item.x,item.y,item.h,item.w)
                    }
                })
            }

            if(Object.prototype.toString.call(config) == "[object Array]") {
                //校验参数
                try{
                   config.forEach(_ => {
                        let xString = _.positionObj.x + ""
                        let wString = _.sizeObj.w + ""

                        //判断传入的参数是否是小数 
                        if(xString.includes(".") || wString.includes(".")) {
                                throw new Error("x 与 w参数不能是小数")
                        }

                        //判断x与w的和是否大于栅格数
                        if(_.positionObj.x + _.sizeObj.w > this.colNum) {
                            throw new Error("x 与 w之和不能大于栅格数")
                        }
                   })
                }
                catch(e) {
                    console.log(e)
                    return 
                }

                this.verticalCompact = false
                this.layout.forEach(item => {
                    config.forEach(_ => {
                        if(item.i == _.i) {
                            item.h = _.sizeObj.h
                            item.w = _.sizeObj.w
                            item.x = _.positionObj.x
                            item.y = _.positionObj.y
                            console.log(item.x,item.y,item.h,item.w)
                        }
                    })
                })
            }
        }
    }
}
</script>

<style lang="scss">
    .layout {
        background: #999;
        height: 500px;
    }
    .hoverStyle {
        border: 1px solid #999;
        // &:hover {
        //     border: 1px solid blue;
        // }
    }
</style>    

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 目录: vue组件系列课程简介 页面结构介绍 安装vue,vue-cli, 安装vant UI框架 导入组件 各页...
    独绽2018阅读 43,730评论 0 6
  • 本文主要讲述页面布局样式方面涉及的知识点,更全面的对CSS相应的技术进行归类、整理、说明,没有特别详细的技术要点说...
    Joel_zh阅读 832评论 0 1
  • 基本介绍 上一篇文章我们介绍了css3 flexbox,今天我们再来说说css3的另外一个强大的功能:Grid。 ...
    老王420阅读 7,558评论 0 49
  • (注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)(注2:更多内容请查看我的目录。) ...
    love丁酥酥阅读 2,603评论 0 2
  • 介绍 vue-grid-layout是一个功能强大的瀑布流布局组件。支持用户拖拽和对改变元素大小,并提供相应的事件...
    AshleyLv777阅读 4,732评论 0 0