安装 vue-drag-resize
npm i vue-drag-resize
引用
import VueDragResize from "vue-drag-resize/src";
将组件div改为VueDragResize
,绑定 宽w
高h
;
<VueDragResizev-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"><divv-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"><VueDragResizev-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>