安装 vue-drag-resize
npm i vue-drag-resize
引用
import VueDragResize from "vue-drag-resize/src";
将组件div改为VueDragResize
,绑定 宽w
高h
;
<VueDragResize
v-for="item in list"
:key="item.id"
class="box"
:style="`transform: translate(${item.x}px, ${item.y}px)`"
:w="item.w"
:h="item.h"
>
我是{{ item.lable }}
</VueDragResize>
修改放置的方法,放置后加上款w
高h
// 放置
const onDrop = (e: any) => {
// e.offsetX e.offsetY 放置组件的位置
list.value.push({
id: currentId++,
x: e.offsetX - widgetX,
y: e.offsetY - widgetY,
w: currentWidget.w, // 当前组件的宽
h: currentWidget.h, // 当前组件的高
lable: currentWidget.lable,
});
};
todo 连线插件:jsPlumb
给原始小组件增加宽高属性
{
type: "pie",
lable: "饼图",
w: 200,
h: 150,
},
完整代码:
<template>
<div id="app">
<!-- 组件列表 -->
<div class="widget-list">
<div
v-for="widget in widgetList"
:key="widget.type"
class="widget"
draggable="true"
:onmousedown="(e:any) => onWidgetMouseDown(e, widget)"
>
{{ widget.lable }}
</div>
</div>
<div class="pannel" @dragover="(e:any) => e.preventDefault()" @drop="onDrop">
<VueDragResize
v-for="item in list"
:key="item.id"
class="box"
:style="`transform: translate(${item.x}px, ${item.y}px)`"
:w="item.w"
:h="item.h"
>
我是{{ item.lable }}
</VueDragResize>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import VueDragResize from "vue-drag-resize/src";
const list: any = ref([]);
const widgetList: any = ref([
{
type: "pie",
lable: "饼图",
w: 200,
h: 150,
},
{
type: "line",
lable: "折线图",
w: 300,
h: 150,
},
{
type: "bar",
lable: "柱状图",
w: 300,
h: 200,
},
]);
// 当前id
let currentId = 0;
// 组件的x和y
let widgetX = 0;
let widgetY = 0;
// 当前拖动的组件
let currentWidget: any = null;
// 放置
const onDrop = (e: any) => {
// e.offsetX e.offsetY 放置组件的位置
list.value.push({
id: currentId++,
x: e.offsetX - widgetX,
y: e.offsetY - widgetY,
w: currentWidget.w, // 当前组件的宽
h: currentWidget.h, // 当前组件的高
lable: currentWidget.lable,
});
};
// 在小组件鼠标落下的时候
const onWidgetMouseDown = (e: any, widget: any) => {
console.log(widget);
// e.offsetX e.offsetX 鼠标落下的位置
widgetX = e.offsetX;
widgetY = e.offsetY;
// 当前拖动的组件 赋给push落下
currentWidget = widget;
};
</script>
<style scoped>
body {
margin: 0;
padding: 0;
}
#app {
width: 100vw;
height: 100vh;
display: flex;
}
.widget-list {
width: 300px;
background-color: #dfdfdf;
}
.pannel {
flex: 1;
background-color: #efefef;
position: relative;
}
.widget {
width: 100px;
height: 100px;
outline: 1px solid red;
font-size: 20px;
text-align: center;
line-height: 100px;
margin: 20px;
}
.box {
outline: 1px solid blue;
position: absolute;
}
</style>