zoukankan      html  css  js  c++  java
  • vue拖拽建站的简单模式vue-grid-layout

    注入依赖

    npm install --save vue-grid-layout

    页面内容

    <-- 这里走个for循环就可以当做需要的拖拽组件区域 -->
    <div  @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"
                 unselectable="on"><img style="100%;height:100%" src="@/utils/11111.jpg"></div>
    <-- 拖拽搭建页面 -->
            <div id="content">
                <grid-layout ref="gridlayout" :layout.sync="layout"
                             :col-num="12"
                             :row-height="30"
                             :is-draggable="true"
                             :is-resizable="false"
                             :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"
                    >
                      <img :src="item.ims" style="100%;height:100%">
                        <span class="text">{{ item.i }}</span>
                    </grid-item>
                </grid-layout>
            </div>

    js事件(引入依赖)

    import VueGridLayout from 'vue-grid-layout'
    const GridLayout = VueGridLayout.GridLayout
    const GridItem = VueGridLayout.GridItem
    let mouseXY = {"x": null, "y": null};
    let DragPos = {"x": null, "y": null, "w": 1, "h": 1, "i": null};

    js事件(参数)

    export default {
      components: {
       GridLayout,
       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"},
                    {"x":6,"y":0,"w":2,"h":3,"i":"3"},
                ],
        };
      },

    js事件(事件功能)

    drag(res){
          let parentRect = document.getElementById('content').getBoundingClientRect();
                let mouseInGrid = false;
                // 拖拽的位置发生变化
                if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
                    // 打开创建
                    mouseInGrid = true;
                }
                // 确认创建后判断是否有新创建的东西
                if (mouseInGrid === true && (this.layout.findIndex(item => item.i === 'drop')) === -1) {
                  console.log('创建添加')
                    this.layout.push({
                        x: (this.layout.length * 2) % (this.colNum || 12),
                        y: this.layout.length + (this.colNum || 12), // puts it at the bottom
                        w: 2,
                        h: 3,
                        i: 'drop',
                    });
                }
                // 查找是否有新创建的东西
                let index = this.layout.findIndex(item => item.i === 'drop');
                // 判断如果没有新创建的
                if (index !== -1) {
                    try {
                        // gridlayout元素下最后一个盒子的样式隐藏
                        this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = "none";
                    } catch {
                    }
                    // gridlayout元素下新添加的盒子
                    let el = this.$refs.gridlayout.$children[index];
                    // 新盒子的位置
                    el.dragging = {"top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left};
                    // 新盒子的位置计算
                    let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
                    // 新创的阴影位置
                    if (mouseInGrid === true) {
                        // 移动的位置(后面的两个值更改阴影大小)
                        this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, 2, 2);
                        console.log(this.layout[index].x,111111)
                        DragPos.i = String(index);
                        DragPos.x = this.layout[index].x;
                        DragPos.y = this.layout[index].y;
                    }
                    // 有过的盒子
                    if (mouseInGrid === false) {
                      console.log(2222)
                        // 移动位置
                        this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 1, 1);
                        // 数组检测输出没有drop的
                        this.layout = this.layout.filter(obj => obj.i !== 'drop');
                    }
                }
        },
        dragend(res){
          console.log(res,"dragend")
          let parentRect = document.getElementById('content').getBoundingClientRect();
                let mouseInGrid = false;
                if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
                    mouseInGrid = true;
                }
                if (mouseInGrid === true) {
          // this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, 1, 1);
        // 添加盒子
    this.layout = this.layout.filter(obj => obj.i !== 'drop'); this.layout.push({ x: DragPos.x, y: DragPos.y, w: 2, h: 2, i: DragPos.i, ims:'https://img1.baidu.com/it/u=1228507199,1542939359&fm=26&fmt=auto&gp=0.jpg' }); // this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1); } },

     参数了解

    <grid-layout
                //  作用        数据类型          必填        备注
                 //===================================================
                // 网格初始化布局  数组       必填  每一项都必须具有i、x、y、w和h属性 属性用作什么 见下方
                :layout.sync="layout"  
                // 表示网格有多少列 数字           非必填    默认为12
                :col-num="12" 
                // 表示一行的高度(以像素为单位) 数字     非必填     默认值为150
                :row-height="30"
                // 表示网格中最大行数 数字          非必填     默认为无穷大
               :maxRows="20"
                // 表示网格项数是否可以拖动 Boolean        非必填     默认为true
                :is-draggable="true"
                // 表示网格是否可以改变带大小 Boolean      非必填     默认为true
                :is-resizable="true"
                // RTL/LTR 的转换 Boolean      非必填 默认为false
                :is-mirrored="false"
                // 容器是否适应内部变化 Boolean  非必填 默认为 true
               :autoSize="ture" 
                // 垂直方向上 是否应该紧凑布局 Boolean 非必填 默认为true
                :vertical-compact="true"
            // 网格之间的边距 两个数字组成的数组 第一个数字为水品距离 第二个为垂直距离 非必填 默认值为 [10,10]
                :margin="[10, 10]"
                // 是否使用css的transforms来排版 非必填 为false时 使用后采用定位方式来布局 默认为true
                :use-css-transforms="true" 
                // 布局是否应响应窗口宽度 非必填 默认false 为true时 会出现一些布局错乱的问题
               :responsive="false" 
               //布局是否应响应为响应布局定义的窗口宽度断点 对象类型 非必填 默认值
                // { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }
               :breakpoints=" { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }"
               // 定义每个断点的列数
               :cols="{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }"
                // 生命周期
                
               @layout-created="layoutCreatedEvent"  // 布局创建事件
                @layout-before-mount="layoutBeforeMountEvent" // 布局安装以前事件
                @layout-mounted="layoutMountedEvent"    // 布局安装事件
                @layout-ready="layoutReadyEvent"    // 布局准备活动
                @layout-updated="layoutUpdatedEvent" // 格子位置 大小更新 
        >
          // 每个单独控制 需要注意的是 每一个属性都要在data中注册一下 不然会导致不能拖拽 或者 不能放大缩小
           <grid-item
             class="echarts_box" 
              :x="layoutData[0].x" // 横向距离
              :y="layoutData[0].y" // 纵向距离
              :w="layoutData[0].w" // 宽度
              :h="layoutData[0].h" // 高度
              :i="layoutData[0].i" // 唯一值 (重复时设置会导致一块放大或缩小)string类型
              @resize="resizeEvent" // 当该元素 被放大缩小触发的事件 
              @move="moveEvent" // 该元素移动时 触发的事件
              @resized="resizedEvent" // 放大缩小结束 触发事件 注意:必须当大小相对上一次发生改变结束时才会触发
              @moved="movedEvent" // 移动结束触发 注意:只有当位置相对上一次发生改变才会触发 
            ></grid-item>
        // for循环 便利数组中的内容 渲染元素 
           // <grid-item v-for="item in layout"
           //          :x="item.x"
           //           :y="item.y"
           //           :w="item.w"
           //            :h="item.h"
           //          :i="item.i">
           //        {{item.i}}
           //</grid-item>
      </grid-layout>
    ​
    import VueGridLayout from 'vue-grid-layout' //文件引入
    const matedata = [
      {
        i: "0", // 索引值 必填 
        h: 4,   // 高度   必填
        w: 7,   // 宽度   必填
        x: 2,   // x 轴距离 必填
        y: 0,   // y轴距离 必填
        minW:5 // 最小宽度 当 w的值小于minW时 采用minW的值 
        minH:3 // 同上
        maxW:8 // 的最大宽度。如果w大于maxW,那么w将被设置为maxW。
        maxH:6 // 同上
        isDraggable:true // 单独控制这一个盒子是否可以拖动 未填写 继承父元素的 非必填
        isResizable:true // 单独控制这一个盒子是否可以调整大小 未填写 继承父元素的 非必填
        static:false // 这个盒子是静态的  不能被其他元素改变位置 会被覆盖在底部
        dragIgnoreFrom: '' // 属性这值为css 选择器 项的哪些元素不应触发项的拖动事件// 具体不知道干嘛的 没有用到
        dragAllowFrom:'' // 属性这值为css 选择器 项的哪些元素应触发项的拖动事件 // 文档这样写的
        resizeIgnoreFrom:''//属性这值为css 选择器 表示项的哪些元素不应触发项的调整大小事件。//来自文档翻译
      },
      {
        h: 1,
        i: "1",
        w: 1,
        x: 0,
        y: 1
      },
      {
        h: 1,
        i: "2",
        w: 1,
        x: 0,
        y: 2
      },
      {
        h: 1,
        i: "3",
        w: 1,
        x: 0,
        y: 3
      }
    ];
    export default {
      data() {
        return {
          layoutData: matedata, //  存放布局数据 数据格式如上
        };
      },
      components: {
        GridLayout, //注册组件
        GridItem // 注册
      },
      methods: {
          // 布局中单元改变事件  i, newX, newY 移动的坐标
          //                i, newH, newW, newHPx, newWPx 变化的大小
                                //newHPx, newWPx 是实际的像素
                            // newH, newW 是数据中的 以每个单位大小为基准点算
        resizeEvent(i, newH, newW, newHPx, newWPx) {
          console.log("大小正在改变",i, newH, newW, newHPx, newWPx);
        },
        moveEvent( i, newX, newY) {
          console.log("正在移动",i, newX, newY);
        },
        resizedEvent(i, newH, newW, newHPx, newWPx) {
          console.log("大小改变完了",i, newH, newW, newHPx, newWPx);
        },
        movedEvent( i, newX, newY) {
          console.log("移动结束了", i, newX, newY);
        },
           // 布局组件的生命周期  参数newLayout=> 布局的数据 每个布局数据
        layoutCreatedEvent(newLayout) {
          console.log("1Created");
        },
        layoutBeforeMountEvent(newLayout) {
          console.log("2Mount");
        },
        layoutMountedEvent(newLayout) {
          console.log("3Mounted");
        },
        layoutReadyEvent(newLayout) {
          console.log("4Ready");
        },
        layoutUpdatedEvent(newLayout) {
          console.log("Updated");
        }
      },
      created() {
      },
      mounted() {
      };
        
    };
  • 相关阅读:
    Android 内存溢出解决方案(OOM) 整理总结
    mysql数据库基本操作
    java基础集合框架——List、Set、Map概述(java集合一)
    Android基础常用日期操作工具类
    Android 中的adapter和作用以及常见的adapter
    Android中的SimpleAdapter
    android中selector使用
    Android 中消息处理机制-Looper、Handler、Thread(一)
    Android 中消息处理机制-Looper、Handler、Thread (二)
    android中MessageQueue , Message , Looper , Handler(三)
  • 原文地址:https://www.cnblogs.com/yishifuping/p/15222645.html
Copyright © 2011-2022 走看看