vue-draggable-resizable定制化可拖动控件

article/2025/8/15 0:40:02

最近遇到一个需求:前端定制化生成合同模板,生成时可以在指定位置拖放指定的控件,可动态编辑指定控件的属性和位置,最后将控件的位置等属性传给后台,后续使用模板签署合同时,乙方可在模板上指定位置签署。

 点击左边控件列表=》添加控件到文件上=》点击文件上的控件激活该控件=》编辑该控件的相关字段=》提交数据

控件类型有多种,支持多个控件同时添加,文本类型支持长宽拉伸设置

刚好有一个很好用的vue插件,那就是今天的猪脚了:vue-draggable-resizable

github地址:https://github.com/mauricius/vue-draggable-resizable,文档挺详细的,使用:

npm i vue-draggable-resizable -S

main.js

import 'vue-draggable-resizable/dist/VueDraggableResizable.css';

可以直接在页面引入:

<template><div class="drag-wrap"><vue-draggable-resizable></vue-draggable-resizable></div>
<template>
import VueDraggableResizable from 'vue-draggable-resizable';
export default {components: { VueDraggableResizable },、、、
}

渲染效果:

已经很棒了,但依然需要做进一步的定制化,满足我们项目的需求:

1、需求:由于控件可以添加多个、多种类,多以肯定会使用v-for生成多个拖拽控件,这就涉及到,当我点击控件对其属性进行编辑的时候需要知道当前点击的控件具体是哪一个。

实际情况:点击事件是没有返回参数

解决办法:把源代码拷贝出来并修改

找到node_modules>vue-draggable-resizable>src>components文件夹下的vue-draggable-resizable.vue文件和src下的utils下的js依赖拷贝出来,我是放到自己项目的src>components下

这样页面的引入方式修改一下:

import VueDraggableResizable from 'vue-draggable-resizable';

这样就把源代码copy出来作为项目的一个组件,方便我们定制化修改

给组件添加customId作为props属性,渲染组件时把唯一id传进去,在actived事件时传递出来,父级页面就知道当前编辑的控件id了,源代码 index.vue

所有activated事件都把id传递出去

源代码 index.vue

demo.vue

            <vue-draggable-resizablev-for="(item, index) in controlsArr":key="item.customId":custom-id="item.customId":h="100":w="100":common-class-name="commonClassName":class-name-active="activedClass"@activated="onActivated"></vue-draggable-resizable>
        // 点击控件onActivated(customId) {// console.log(customId);this.activedId = customId;},

2、需求:激活某一控件后,需在右侧编辑该控件的属性,此时该控件必须高亮

实际:默认情况下,只要不是点击控件自身,不管点击页面哪里,该控件都会失去焦点,不再高亮,从源码可以看到做了判断:

官网有一个配置属性,preventDeactivation=true时点击其它地方,已激活的控件不会失去焦点,对于单个控件来说没问题,但当页面有多个控件时,即便是点击其它控件也不会失去焦点,这样就没法切换控件,无法满足要求。

解决办法:修改源码判断标准

新增props属性:commonClassName用于区分点击的元素是否为控件或控件内slot元素

源代码 index.vue

绑定到元素上

源代码 index.vue

修改判定逻辑

源代码 index.vue

使用组件时,组件及slot元素统一都绑上一个commonClassName

demo.vue

如果点击的元素不是控件(即没有统一class属性的元素),才让上一个激活的控件失去焦点,就达到了切换的功能。

3、需求:点击左侧控件列表添加控件时,默认当前添加控件为激活状态,即高亮,不用再一次点击才激活

解决办法:修改源码,添加控件的同时,手动触发组件的activated事件

源代码 index.vue

可以看到activated事件是在elementDown事件中触发的,在控件添加完后使用this.$refs.refName.method()方法调用组件内部方法即可。

添加控件的同时绑定一个唯一的id,我这里用的是时间戳

demo.vue

添加控件:

demo.vue

// 添加控件addControl(type) {const controlObjMap = {1: {customId: Date.now(),width: 200,height: 30,x: 300,y: 40,className: 'lq-draggable-text',type: 'text', // 控件类型handles: ['mr'],name: '文本框',fontsSize: 10,signatory: 0 // 签署方默认甲方},2: {customId: Date.now(),width: 80,height: 80,x: 0,y: 140,type: 'seal', // 控件类型name: '印章',signatory: 0 // 签署方默认甲方},3: {customId: Date.now(),width: 80,height: 40,x: 0,y: 260,type: 'sign', // 控件类型name: '签名',signatory: 0 // 签署方默认甲方},4: {customId: Date.now(),width: 80,height: 30,x: 0,y: 380,type: 'date', // 控件类型name: '日期',fontsSize: 10,signatory: 0 // 签署方默认甲方},5: {customId: Date.now(),width: 80,height: 30,x: 200,y: 380,type: 'select', // 控件类型name: '选项',fontsSize: 10,signatory: 0 // 签署方默认甲方}};this.controlsArr.push(controlObjMap[type]);this.setControlActive(controlObjMap[type].customId);},// 手动设置刚才添加的控件为选中状态setControlActive(customId) {this.$nextTick(() => {// console.log(this.$refs[customId][0]);this.$refs[customId][0].elementDown();});}

由于外部调用elementDown方法,没有event对象最为参数,所以需要对该函数做个处理

源代码 index.vue

      elementDown(e) {// 没有e则是外部调用方式const target = e ? e.target || e.srcElement : '';const classNameArr = target.className? target.className.split(' '): [];// 被点击元素不是关闭按钮if (classNameArr.includes('close')) {return;}if (e && this.$el.contains(target)) {、、、、、} else {// 用于父组件直接调用if (!this.enabled) {// console.log(666);this.enabled = true;this.$emit('activated', this.customId);this.$emit('update:active', true);if (this.draggable) {this.dragging = true;}}}},

4、需求:每个控件上需要一个关闭按钮,点击时需单独处理,和激活事件区分开来

给关闭按钮绑定close属性

demo.vue

源代码 index.vue

ok!这样修修改改总算能满足要求了,在此基础上继续扩展也很方便了。

项目地址:https://github.com/LandQ123/lq-components.git


http://chatgpt.dhexx.cn/article/8LlZanBI.shtml

相关文章

使用 vue.draggable 实现拖拽、克隆

这是大佬的博客 https://blog.csdn.net/zjiang1994/article/details/79809687 里面对vue.draggable的一些方法和属性&#xff0c;进行了详解&#xff0c;非常的详细&#xff0c;比官网的还要详细哦&#xff01;给大佬点赞&#xff01;&#xff01;&#xff01; 这是vue.draggab…

React Draggable 实现拖拽 - 最详细中文教程 - 卡拉云

本文首发&#xff1a;《React Draggable 实现拖拽 - 最详细中文教程 - 卡拉云》 React Draggable 是 react 生态中&#xff0c;最好用的拖拽实现库之一。如果你的应用中需要实现拖拽功能&#xff0c;可以尝试用 react-draggable&#xff0c;它可以满足多数情况下的拖拽需求&am…

draggable属性的应用

draggable属性用来定义元素是否可以拖动。 效果图&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>draggable属性的应用</title> </head> <body> <h3>元素拖…

draggable 和 sortable的JS原生实现

概要 本文主要利用html 5的draggable原生特性&#xff0c;实现一个可拖拽的效果。我们可以创建包含多个页面节点的容器&#xff0c;每个容器可以包含多个节点。通过拖拽&#xff0c;可以移动一个容器内的节点到其他容器&#xff0c;每个容器内的节点和以通过拖拽改变排列顺序。…

vue3使用拖拽组件draggable.next的使用教程【保姆级】

环境&#xff1a;vue3setup语法 首先放官方文档的链接&#xff1a; 中文版本&#xff1a; https://www.itxst.com/vue-draggable-next/tutorial.html &#xff08;民间翻译&#xff09; 英文版本&#xff1a;https://github.com/SortableJS/vue.draggable.next 因为自己写的过程…

vue的拖拽插件: vue.draggable

中文文档地址: vue.draggable中文文档 - itxst.comVue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动&#xff0c;可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作&#xff0c;总之是一款非常优秀的…

react-draggable实现拖拽详解

react-draggable 属性常用属性属性列表 事件列表举例首先安装 react-draggable实现移动 希望小编写的能够帮助到你&#x1f618; 属性 常用属性 属性默认值介绍axisxhandle拖动的方向&#xff0c;可选值 x ,y,bothhandle无指定拖动handle的classposition无handle的位置&#…

draggable拖拽组件使用

项目开发中需要用到拖拽组件&#xff0c;因为前端技术框架是vue&#xff0c;这里就使用了vue的一款拖拽插件vue.draggable&#xff0c;一般基本的需求都能满足&#xff0c;这里使用了多个draggable嵌套&#xff0c;达到两级之前相互拖拽的功能。 以下是类似teambition的效果图…

原生JS的拖拽属性draggable(详解)

摘要 作为h5新增的属性draggable&#xff0c;它能够给与一切的html元素拖动的效果。而在这个属性之下&#xff0c;也有着关于拖动效果的各个方法。 而这一篇文章&#xff0c;主要就是说一下关于draggable属性的使用以及工作场景。 1.了解draggable属性的使用 对我来讲&#…

EasyUI基础入门之Draggable(拖拽)

前面学习了easyui基础的解析器,加载器。对于他们入门阶段我们只需简单的了解下即可&#xff0c;毕竟先阶段并不会太过深入。接下来根据easyui官网文档的顺序安排学习下Draggable插件。 Draggable是什么 Draggable是easyui中用于实现拖拽功能的一个插件。利用它&#xff0c;我们…

jts-core 使用说明(二)

jts-core 使用说明 示例代码库 JTS源码底层使用说明&#xff0c;通过一下章节介绍说明 层次结构 org.locationtech.jts: algorithm - 算法包jts-io-common - I/O classes for open spatial formatsgeom - geom基础包geom.prep - 对适当准备的几何图形执行优化的几何操作类e…

java jts获取线上任意一点到起点的距离

java jts获取线上任意一点到起点的距离 近期项目要求计算某段公路上一辆车的运行轨迹&#xff0c;通过路上的设备实时获取车辆的经纬度信息并发送到后台接收。 抽象出来就是获取线上任意一点到起点的距离&#xff0c;按照一定每秒一次的频率去计算就获取该点的运动轨迹了。 主要…

JTS-Geometry 使用说明(五)

org.locationtech.jts.geom.Geometry 使用说明 示例代码库 Geometry 经纬度操作类 Geometry类继承关系 说明 平面、线性几何操作抽象类 提供的相关方法: 1.基础方法&#xff1a; 1.1 getLength:获取长度&#xff0c;线几何返回点与点之间的长度之和&#xff1b;闭合几何返回…

JAVA使用JTS 判断坐标点是否在坐标多边形内部

JAVA使用JTS 判断坐标点是否在坐标多边形内部 思路Geometry之间的关系API及参考博客代码依赖工具类测试类 思路 判断坐标点是否在坐标多边形内部&#xff0c;首先不能直接计算坐标点&#xff0c;是需要字符串坐标点转化为地理空间数据Geometry&#xff0c;然后使用JTS包中提供…

JTS学习笔记

JTS学习笔记 基础的类 Geometry geom对象Coordinate坐标类Point Point对象MultiPoint 基本对象MultiPoint等等GeometryFactory工厂对象PreparedGeometryFactoryPreparedGeometry 几何对象Geometry public abstract class Geometry implements Cloneable, Comparable, Seria…

JTS-Angle GIS几何角度计算使用说明(十八)

org.locationtech.jts.algorithm.Angle 角度计算使用说明 示例代码库 Angle 角度计算 1.Angle.angle(p0,p1) public static double angle(Coordinate p0, Coordinate p1) {double dx p1.x - p0.x;double dy p1.y - p0.y;return Math.atan2(dy, dx); }返回与x轴正方向的夹…

java jts_Java Topology Suite (JTS)与空间数据模型

JTS是Java的处理地理数据的API&#xff0c;它提供以下功能&#xff1a; 实现了OGC关于简单要素SQL查询规范定义的空间数据模型 一个完整的、一致的、基本的二维空间算法的实现&#xff0c;包括二元运算(例如touch和overlap)和空间分析方法(例如intersection和buffer) 一个显示的…

java jts点到面的距离_jts-空间索引

前言&#xff1a; 如果您对JTS这三个词还是没有一个概念&#xff0c;那么推荐您关注一下sinoly的博客。这个我能够找到为数不多的关于jts的中文资料。 http://www.blogjava.net/sinoly/archive/2007/02/09/99042.html 下面这段话就是摘抄自sinoly老兄的博客&#xff1a; ......…

JTS Geometry关系判断和分析

关系判断 Geometry之间的关系有如下几种&#xff1a; 相等(Equals)&#xff1a; 几何形状拓扑上相等。 脱节(Disjoint)&#xff1a; 几何形状没有共有的点。 相交(Intersects)&#xff1a; 几何形状至少有一个共有点&#xff08;区别于脱节&#xff09; 接触(Touches)&a…

JTS Geometry用例分析

微信搜索&#xff1a;“二十同学” 公众号&#xff0c;欢迎关注一条不一样的成长之路 拓扑关系 GeometryTest import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import…