vue Grid Layout - A grid layout system for Vue

东郭瀚玥
2023-12-01

前言

What is Vue Grid Layout?

vue-grid-layout is a grid layout system, like Gridster, for Vue.js. Heavily inspired by React-Grid-Layout;


一、官方文档

官方文档地址

Demo


二、NPM

npm install vue-grid-layout@2.3.9--save

三、Import the library and add to other Vue components

   import VueGridLayout from 'vue-grid-layout';

   export default {
       components: {
           //核心组件
           GridLayout: VueGridLayout.GridLayout,
           GridItem: VueGridLayout.GridItem
       },
   }
   

四、属性、事件、样式

<template>
  <grid-layout
    :layout="LayoutData"//数据源。值必须为 Array,其数据项为 Object。 每条数据项必须有 i, x, y, w 和 h 属性
    :auto-size="false"//容器自动调整大小,默认true
    :col-num="12"//栅格的数量,默认12
    :row-height="20"//行高,默认150,值越小,越精确,值越大,拖拽幅度越大
    :max-rows="100"//最大行数,默认不限制
    :is-draggable="true"//是否可以拖拽,默认true
    :is-resizable="false"//是否可以改变大小,默认true
    :vertical-compact="false"//标识栅格中的元素是否可镜像反转,默认false
    :margin="[10, 10]"//值必须是包含两个 Number的数组,数组中第一个元素表示水平边距,第二个表示垂直边距,单位为像素;
    :use-css-transforms="true" //是否使用CSS属性,默认true
    :vertical-compact="true" //布局是否垂直压缩,默认true
    :prevent-collision="true"//防止碰撞属性,值设置为ture时,栅格只能拖动至空白处
    :responsive="true"//布局是否为响应式
    :breakpoints="{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }"//为响应式布局设置断点
    :cols="{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }"//设置每个断点对应的列数
    :use-style-cursor="true"//是否使用动态鼠标指针样式。当拖动出现卡顿时,将此值设为 false也许可以缓解布局问题
    @layout-created="layoutCreatedEvent"
    @layout-before-mount="layoutBeforeMountEvent"
    @layout-mounted="layoutMountedEvent"
    @layout-ready="layoutReadyEvent"
    @layout-updated="layoutUpdatedEvent"
    @breakpoint-changed="breakpointChangedEvent"
  >
    <grid-item v-for="item in LayoutData" :key="item.i"
               :x="item.x"//水平相对位置,Number,必填,自然数
               :y="item.y"//垂直相对位置,Number,必填,自然数
               :w="item.w"//宽度,Number,必填,自然数,值与col-num有关系,倍数
               :h="item.h"//高度,Number,必填,自然数,值与row-height有关系,倍数
               :i="item.i"//String,必填
               :minW="item.minW"//栅格元素的最小宽度,值为colWidth的倍数,如果w小于minW,则minW的值会被w覆盖
               :minH="item.minH"//栅格元素的最小高度,值为rowHeight的倍数,如果h小于minH,则minH的值会被h覆盖
               :maxW="item.maxW"//栅格元素的最大宽度,值为colWidth的倍数,如果w大于maxW,则maxW的值会被w覆盖
               :maxH="item.maxH"//栅格元素的最大高度,值为rowHeight的倍数,如果h大于maxH,则maxH的值会被h覆盖
               :is-draggable=null//标识栅格元素是否可拖拽。如果值为null则取决于父容器
               :is-resizable=null//标识栅格元素是否可调整大小。如果值为null则取决于父容器
               :static="false"//标识栅格元素是否为静态的(无法拖拽、调整大小或被其他元素移动)
               :drag-ignore-from="a, button"//标识栅格元素中哪些子元素无法触发拖拽事件
               :drag-allow-from=null//标识栅格元素中哪些子元素可以触发拖拽事件,如果值为null则表示所有子元素
               :resize-ignore-from="a, button"//strig,标识栅格元素中哪些子元素无法触发调整大小的事件
               @resize="resizeEvent"//大小改变事件
               @move="moveEvent"//位置移动事件
               @resized="resizedEvent"//大小改变结束事件
               @moved="movedEvent">//位置移动结束事件
               @container-resized="containerResizedEvent"//栅格元素/栅格容器更改大小的事件
      <component :is="item.component" ></component>//定位展示vue组件
    </grid-item>
  </grid-layout>
</template>

<script>
  import Vue from 'vue'
  import VueGridLayout from 'vue-grid-layout'
  Vue.use(VueGridLayout)

  var LayoutData = [
    {"x":0,"y":0,"w":1,"h":1,"i":"0","component":"vue组件"},
    {"x":0,"y":1,"w":1,"h":1,"i":"1","component":"vue组件"},
    {"x":0,"y":2,"w":1,"h":1,"i":"2","component":"vue组件"},
    {"x":0,"y":3,"w":1,"h":1,"i":"3","component":"vue组件"},
    {"x":1,"y":0,"w":1,"h":1,"i":"4","component":"vue组件"},
    {"x":1,"y":1,"w":1,"h":1,"i":"5","component":"vue组件"},
    {"x":1,"y":2,"w":1,"h":1,"i":"6","component":"vue组件"},
    {"x":1,"y":3,"w":1,"h":1,"i":"7","component":"vue组件"},
    {"x":2,"y":0,"w":1,"h":1,"i":"8","component":"vue组件"},
    {"x":2,"y":1,"w":1,"h":1,"i":"9","component":"vue组件"},
    {"x":2,"y":2,"w":1,"h":1,"i":"10","component":"vue组件"},
    {"x":2,"y":3,"w":1,"h":1,"i":"11","component":"vue组件"},
    {"x":3,"y":0,"w":1,"h":1,"i":"12","component":"vue组件"},
    {"x":3,"y":1,"w":1,"h":1,"i":"13","component":"vue组件"},
    {"x":3,"y":2,"w":1,"h":1,"i":"14","component":"vue组件"},
    {"x":3,"y":3,"w":1,"h":1,"i":"15","component":"vue组件"},
    {"x":4,"y":0,"w":1,"h":1,"i":"16","component":"vue组件"},
    {"x":4,"y":1,"w":1,"h":1,"i":"17","component":"vue组件"},
    {"x":4,"y":2,"w":1,"h":1,"i":"18","component":"vue组件"},
    {"x":4,"y":3,"w":1,"h":1,"i":"19","component":"vue组件"}
  ];

  var GridLayout = VueGridLayout.GridLayout;
  var GridItem = VueGridLayout.GridItem;

  export default {
    name: 'Layout',
    components: {
      GridLayout,
      GridItem,
    },
    data () {
      return {
        layout: LayoutData,
        newX:0,
        newY:0
      }
    },
    mounted () {

    },
    methods:{
      moveEvent: function(i, newX, newY,e){
        //console.log(e)
        //console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY);
      },
      resizeEvent: function(i, newH, newW){
        //console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW);
      },
      movedEvent: function(i, newX, newY,e){
        //console.log(e)
        //console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY);
      },
      resizedEvent: function(i, newH, newW, newHPx, newWPx){
        //console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
      }
    },
    /**
     * 
     * @param i the item id/index
     * @param newH new height in grid rows 
     * @param newW new width in grid columns
     * @param newHPx new height in pixels
     * @param newWPx new width in pixels
     * 
     */
    containerResizedEvent: function(i, newH, newW, newHPx, newWPx){
        console.log("CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
    },
    //对应Vue生命周期的created
    layoutCreatedEvent: function(newLayout){
      console.log("Created layout: ", newLayout)
    },
    //对应Vue生命周期的beforeMount
    layoutBeforeMountEvent: function(newLayout){
      console.log("beforeMount layout: ", newLayout)
    },
    //对应Vue生命周期的mounted
    layoutMountedEvent: function(newLayout){
      console.log("Mounted layout: ", newLayout)
    },
    //当完成mount中的所有操作时生成的事件
    layoutReadyEvent: function(newLayout){
      console.log("Ready layout: ", newLayout)
    },
    //布局updated事件,更新事件(布局更新或栅格元素的位置重新计算)
    layoutUpdatedEvent: function(newLayout){
      console.log("Updated layout: ", newLayout)
    },
    /**
     * 
     * @param newBreakpoint the breakpoint name
     * @param newLayout the chosen layout for the breakpoint
     * 断点更改事件,每次断点值由于窗口调整大小而改变
     */
    breakpointChangedEvent: function(newBreakpoint, newLayout){
        console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout );
    },

  }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .vue-grid-layout {
     position: relative;
     width:800px;
     height:450px;
     /*overflow: hidden;*/
     background: url('../../assets/desktop_background.png') no-repeat;
  }
  .vue-grid-layout>div {
     position: absolute;
     background: indianred;
  }
<!--占位符的默认css -->
.vue-grid-item.vue-grid-placeholder {
    background: red !important;
    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;
}  
<!--覆盖默认样式-->
.container .vue-grid-item.vue-grid-placeholder {
    background: green;
}

<!-- -->

<!-- -->

<!-- -->
</style>
 类似资料:

相关阅读

相关文章

相关问答