拖拽

2022-10-08

参考网站
https://github.com/gorkys/vue-draggable-resizable-gorkys
第一种方式:拖拽vue-draggable-resizable-gorkys

一、安装引入

1.安装
$ npm install --save vue-draggable-resizable-gorkys

2.在main.js中引入
//main.js
import Vue from 'vue'
import vdr from 'vue-draggable-resizable-gorkys'
// 导入默认样式
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'
Vue.component('vdr', vdr)

二、新建一个文件夹tuozuai=>index.vue。
注意:resizing函数里默认有四个参数x,y,weight,height,如要传参需要用箭头函数的形式
例: v-on:resizing="(x,y,width,height)=>{onResize(x,y,width,height,item)}"

<template>
  <div id="app">
    <div
      style="
        height: 800px;
        width: 1200px;
        border: 1px solid red;
        position: relative;
        margin: 0 auto;
      "
    >
      <vue-draggable-resizable
        v-for="(item, index) in dragDropList"
        :key="item.title"
        :w="item.w"
        :h="item.h"
        :parent="true"
        :x="item.y"
        :index="item.i"
        :title="item.title"
        :debug="false"
        :min-width="100"
        :min-height="100"
        :isConflictCheck="true"
        :snap="true"
        :snapTolerance="1"
        @refLineParams="getRefLineParams"
        v-on:dragging="(x,y)=>{onDrag(x,y,item)}"
        v-on:resizing="(x,y,width,height)=>{onResize(x,y,width,height,item)}"
        class="test1"
      >
        <p>{{item.title}}</p>
      </vue-draggable-resizable>
      <!--辅助线-->
      <span
        class="ref-line v-line"
        v-for="item in vLine"
        :key="item.id"
        v-show="item.display"
        :style="{
          left: item.position,
          top: item.origin,
          height: item.lineLength,
        }"
      />
      <span
        class="ref-line h-line"
        v-for="item in hLine"
        :key="item.id"
        v-show="item.display"
        :style="{
          top: item.position,
          left: item.origin,
          width: item.lineLength,
        }"
      />
      <!--辅助线END-->
    </div>
    <button @click="btn()">保存</button>
  </div>
</template>

<script>
import VueDraggableResizable from "vue-draggable-resizable-gorkys";
import "vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css";
export default {
  name: "app",
  components: {
    VueDraggableResizable,
  },
  data() {
    return {
      dragDropList: [
        { title: "red", w: 300, h: 300, x: 0 , y:0, i:0},
        { title: "blue", w: 200, h: 200, x: 400 ,y:400, i:1},
        { title: "green", w: 100, h: 100, x: 700 ,y:700,  i:2},
      ],
      vLine: [],
      hLine: [],
      isTrue: true,
      x:"",
      y:"",
      width:"",
      height:"",
      dataList:"",
    };
  },
  methods: {
    onResize: function (x,y,width,height,data) {
      data.x = x;
      data.y = y;
      data.w = width;
      data.h = height;
      
      console.log(x,y,width,height,data)
      console.log(data)
    },
    onDrag: function (x, y, data) {
      data.x = x;
      data.y = y;
      console.log(data)
    },
    btn() {
     console.log("dragDropList",this.dragDropList)
    },
    // 辅助线回调事件
    getRefLineParams(params) {
      const { vLine, hLine } = params;
      let id = 0;
      this.vLine = vLine.map((item) => {
        item["id"] = ++id;
        return item;
      });
      this.hLine = hLine.map((item) => {
        item["id"] = ++id;
        return item;
      });
    },
  },
};
</script>

<style>
.test1 {
  background-color: rgb(239, 154, 154);
}
.test2 {
  background-color: rgb(129, 212, 250);
}
.test3 {
  background-color: rgb(174, 213, 129);
}
</style>

三、实现效果

第二种方式:拖拽vue-grid-layout
https://www.cnblogs.com/yasoPeng/p/9961732.html
一、安装引入

先跑一遍demo 运行起来。

# install with npm    
npm install vue-grid-layout --save

二、新建一个文件夹tuozuai=>index.vue。

<template>
  <div id="gidlayout">
    <!-- <h1 style="text-align: center">Vue Grid Layout</h1> -->
    <!--<pre>{{ layout | json }}</pre>-->
    <div>
      <div class="layoutJSON">
        Displayed as <code>[x, y, w, h]</code>:
        <div class="columns">
          <div class="layoutItem" v-for="item in layout" :key="item.i">
            <b>{{ item.i }}</b
            >: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]
          </div>
          <button @click="clicked">保存</button>
        </div>
      </div>
    </div>
    <div id="content">
      <grid-layout
        :margin="[parseInt(marginX), parseInt(marginY)]"
        :layout.sync="layout"
        :col-num="parseInt(colNum)"
        :row-height="rowHeight"
        :is-draggable="draggable"
        :is-resizable="resizable"
        :is-mirrored="mirrored"
        :prevent-collision="preventCollision"
        :vertical-compact="true"
        :use-css-transforms="true"
      >
        <grid-item
          v-for="item in layout"
          :key="item.i"
          :static="item.static"
          :x="item.x"
          :y="item.y"
          :w="item.w"
          :h="item.h"
          :i="item.i"
          @resized="resized"
          @moved="moved"
        >
          {{ item.i }}
        </grid-item>
      </grid-layout>
      <hr />
    </div>
  </div>
</template>

<script>
import VueGridLayout from 'vue-grid-layout';
let testLayout = [
  {
    x: 0,
    y: 0,
    w: 6,
    h: 2,
    i: '0',
    resizable: true,
    draggable: true,
    static: false,
  },
  {
    x: 2,
    y: 0,
    w: 2,
    h: 4,
    i: '1',
    resizable: null,
    draggable: null,
    static: false,
  },
  {
    x: 4,
    y: 0,
    w: 2,
    h: 5,
    i: '2',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 6,
    y: 0,
    w: 6,
    h: 3,
    i: '3',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 8,
    y: 0,
    w: 2,
    h: 3,
    i: '4',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 10,
    y: 0,
    w: 2,
    h: 3,
    i: '5',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 0,
    y: 5,
    w: 2,
    h: 5,
    i: '6',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 2,
    y: 5,
    w: 2,
    h: 5,
    i: '7',
    resizable: false,
    draggable: false,
    static: false,
  },
  {
    x: 4,
    y: 5,
    w: 2,
    h: 5,
    i: '8',
    resizable: false,
    draggable: false,
    static: false,
  },
];

export default {
  name: 'girdLayout',
  components: {
    GridLayout: VueGridLayout.GridLayout,
    GridItem: VueGridLayout.GridItem,
  },
  data() {
    return {
      layout: JSON.parse(JSON.stringify(testLayout)),
      layout2: JSON.parse(JSON.stringify(testLayout)),
      draggable: true,
      resizable: true,
      mirrored: false,
      responsive: true,
      preventCollision: false,
      rowHeight: 30,
      colNum: 12,
      index: 0,
      marginX: 10,
      marginY: 10,
    };
  },
  mounted: function () {
    this.index = this.layout.length;
  },
  methods: {
    clicked: function () {
      console.log(this.layout);
      // window.alert("CLICK!");
    },
    moved: function (i, newX, newY) {
      console.log('111### MOVED i=' + i + ', X=' + newX + ', Y=' + newY);
    },
    resized: function (i, newH, newW, newHPx, newWPx) {
      console.log(this.layout[i]);
      // console.log(
      //   '### RESIZED i=' +
      //     i +
      //     ', H=' +
      //     newH +
      //     ', W=' +
      //     newW +
      //     ', H(px)=' +
      //     newHPx +
      //     ', W(px)=' +
      //     newWPx
      // );
    },
    // containerResized: function(i, newH, newW, newHPx, newWPx){
    //     console.log("### CONTAINER RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
    // },
  },
};
</script>


 

<style lang="scss">
#gidlayout {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /*text-align: center;*/
  color: #2c3e50;
  /*margin-top: 60px;*/
}
/*** EXAMPLE ***/
#content {
  width: 100%;
  margin-top: 10px;
}

.vue-grid-layout {
  background: #eee;
}

// .layoutJSON {
//   background: #ddd;
//   border: 1px solid black;
//   margin-top: 10px;
//   padding: 10px;
// }

// .eventsJSON {
//   background: #ddd;
//   border: 1px solid black;
//   margin-top: 10px;
//   padding: 10px;
//   height: 100px;
//   overflow-y: scroll;
// }

.columns {
  -moz-columns: 120px;
  -webkit-columns: 120px;
  columns: 120px;
}

.vue-resizable-handle {
  z-index: 5000;
  position: absolute;
  width: 20px;
  height: 20px;
  bottom: 0;
  right: 0;
  background-position: bottom right;
  padding: 0 3px 3px 0;
  background-repeat: no-repeat;
  background-origin: content-box;
  box-sizing: border-box;
  cursor: se-resize;
}

.vue-grid-item:not(.vue-grid-placeholder) {
  background: #ccc;
  border: 1px solid black;
}


</style>

三、实现效果

本文地址:https://blog.csdn.net/qq_42401946/article/details/111975169

《拖拽.doc》

下载本文的Word格式文档,以方便收藏与打印。