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 选择器字符串。

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

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

好了,总结上面的内容:

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

vue-grid-layout组件的改装--暴露布局方法_第1张图片
具体实现思路无非就是重新给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>    

你可能感兴趣的:(Vue)