都好久没有更新了 最新在做一个关于低代码拖拽搭建实现大屏应用的项目 以下是一些关于其中的核心点以及我在过程中遇到的问题 希望能帮助到正在攻克这块的程序员们
基础页面大概就是这样 拖拽是基于vue-draggable-resizable(vue2) 插件做的 但是这个插件有升版
vue-draggable-resizable-gorkys (新增冲突检测 和 辅助线功能) 推荐大家下载新版有新增的功能
GitHub - gorkys/vue-draggable-resizable-gorkys: Vue 用于可调整大小和可拖动元素的组件并支持冲突检测、元素吸附、元素对齐、辅助线
这是属性地址
基 本 - 基 本 组 件 ⋅ Storybook (tingtas.com) 这个是在线演示的项目
基础下载和基础属性大家去主页面自己看下 比较简单
我主要讲下中间过程中遇到的坑 (大家使用这个代码肯定是用来开发低代码平台 然后我列出的问题肯定是大家使用这个插件遇到的问题)
1.选中组件时调整他的属性样式 点击右侧面板 他的选中状态消失了
目前我的功能是他选中点击 右边红框区域显示他的属性和信息 然后可以修改他 但是使用这个插件点击其他区域他的选中状态会消失
1.解决方案
<vue-draggable-resizableclass="draggable-item":w="item.width":h="item.height":x="item.position.x":y="item.position.y":z="item.index":snap="true":snap-tolerance="20"@dragging="onDrag"@dragstop="dragStop"@resizing="onResize"@resizestop="onResizeStop"@activated="onActivated(item, item.type)"@deactivated="onDeactivated":prevent-deactivation="true":parent="false"v-for="(item, index) in dataList":key="index"//新添加了一标识 让其标识等于唯一值时选中:active="selectComponentId == item.identifier":style="{ display: item.hideStatus == true ? 'none' : 'block' }":draggable="item.lockStatus":resizable="item.lockStatus":ref="`draggable${item.identifier}`"@click="draggableClickFn(item.position.x,item.position.y,item.width,item.height)">
//因为他的选中样式只有那个几个勺匙 我加了一个淡绿色的透明背景 突出选中样式<imgclass="lineImg"v-show="selectComponentId == item.identifier"src="../../../../assets/images/liner-bgc.png"alt=""@contextmenu.prevent="showContextMenu($event, item)"/></vue-draggable-resizable>//然后在点击事件时将其唯一值赋予它onActivated(data, type) {that.selectComponentId = data.identifier;},// 监听画布外点击事件handleKeepActive(e) {let that = this;const target = e.target || e.srcElement;if (that.$refs.canvasRef.contains(target)) {that.isPreventDeActive = true;// console.log('在区域内');that.selectComponentId = null;this.$emit("update:selectComponentId", this.selectComponentId);} else {that.isPreventDeActive = false;// console.log('在区域外');}return false;},
我监听画布完区域 清除其选中状态 点击其他区域他的选中状态不清除(这样就可以设置他的样式)
2. 画布缩放后他的拖拽位置发生偏差 拖拽不动
大家可以看到我右下角有缩放按钮 他的画布是可以缩放的 然后他的拖拽位置会受到缩放元素 他的拖拽位置会发生偏差 (这里只提供我的解决方法 大家有新的方法可以解决也可以私聊我 感谢)
//新加一个点击事件 他的onActivated 事件只会在未选中时选中后只会触发一次 我们需要获取他的每次初始位置
draggableClickFn(x, y, w, h) {this.dragStartX = x;this.dragStartY = y;},//拖拽中onDrag: function (x, y) {if (this.selectComponentId) {const item = this.dataList.find((item) => item.identifier == this.selectComponentId);if (item) {let scale = this.scale;if (!this.dragStartX && !this.dragStartY) {// 第一次拖拽时记录初始位置this.dragStartX = x;this.dragStartY = y;}
//计算逻辑const diffX = x - this.dragStartX;const diffY = y - this.dragStartY;this.newX = Math.floor(diffX / this.scale + item.position.x);this.newY = Math.floor(diffY / this.scale + item.position.y);
//这里要获取到当前的元素 因为只设置他的位置值时 虽然x y数值动了 但是他的元素本身没有设置// let element = this.$refs.draggableRef;const refName = `draggable${this.selectComponentId}`;let element = this.$refs[refName][0];element.style.transform = `translate(${this.newX}px, ${this.newY}px)`;}}// console.log(this.dataList, 'dataList');},
//拖拽结束dragStop(x, y) {if (this.selectComponentId) {const item = this.dataList.find((item) => item.identifier == this.selectComponentId);if (item) {
//拖拽结合后直接将数值赋予到当前的组件中item.position.x = this.newX;item.position.y = this.newY;this.dragStartX = null;this.dragStartY = null;this.$emit("update:dataList", this.dataList);}}},
3.他的大小拉伸也会受到偏移的影响 但是我使用上面的拖拽时相同的方法时 会出现问题等我完整解决后在分享给大家 大家有好的解决方法也可以私信我 感谢
大概复杂的就只有这几点 我可能讲解的不仔细 但是这个是提供给在深入了解这个插件做项目的小伙伴 初了解的小伙伴 可以去插件主页面了解一下吧
大家还有其他问题就跟我说 我看我使用过程中还有没有碰到类似的