表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录
- 使用的拖拽组件时vuedraggable。下面放上局部示例截图。
- 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义
- 要使用 :clone, 而不是@clone。我想应该是因为draggable标签比较特。
- 另外在使用**:clone时要将此响应添加到from draggable标签中,也就是如果从左向右拖拽标签复制,要放到左侧标签中才会起作用。意思是在赋值时对被赋值的组件对象加工处理后才会被放到右侧标签**
<template><div class="form-designer"><!-- 左侧面板:可拖拽的控件 --><div class="component-panel"><h3>控件库</h3><draggable:list="availableComponents":group="{ name: 'components', pull: 'clone' }":clone="handleComponentClone"><div v-for="(comp, index) in availableComponents" :key="index" class="component-item">{{ comp.label }}</div></draggable></div><!-- 中间画布:设计区域 --><div class="design-canvas"><h3>表单设计区</h3><draggablev-model="formStructure":group="{ name: 'components', put: true }"@add="(item) => onComponentAdded(item)"><transition-group name="fade" tag="div" class="form-items"><divv-for="item in formStructure":key="item.id"class="form-item":class="{ selected: selectedItem === item }"@click="selectComponent(item)"><el-form><component:is="item.type"v-model="formData[item.vModel]":label="item.label":options="item.options":required="item.required" /></el-form><!-- {{ item.label }} --></div></transition-group></draggable></div><!-- 右边配置面板:属性编辑 --><div class="config-panel"><h3>属性设置</h3><div v-if="selectedItem"><el-form label-position="top"><el-form-item label="字段名称"><el-input v-model="selectedItem.label" /></el-form-item><el-form-item label="绑定字段名"><el-input v-model="selectedItem.vModel" /></el-form-item><el-form-item label="默认值"><el-input v-model="formData[selectedItem.vModel]" /></el-form-item><el-form-item label="是否必填"><el-switch v-model="selectedItem.required" /></el-form-item></el-form></div></div></div>
</template><script>
import draggable from 'vuedraggable';
import DynamicInput from './components/Input.vue';
import DynamicSelect from './components/Select.vue';
import DynamicCheckboxGroup from './components/CheckboxGroup.vue';
import DynamicDatePicker from './components/DatePicker.vue';
import DynamicUpload from './components/UploadFile.vue';
import DynamicImageUpload from './components/UploadImage.vue';
import { options } from 'runjs';
import { start } from 'nprogress';
import cloneDeep from 'lodash.clonedeep';export default {name: 'FormDesigner',components: {draggable,DynamicInput,DynamicSelect,DynamicCheckboxGroup,DynamicDatePicker,DynamicUpload,DynamicImageUpload},data() {return {// textarray: ['1', '2', '3'],// 可拖拽控件列表availableComponents: [{ type: 'DynamicInput', label: '单行文本', required: false, vModel: 'text' },{ type: 'DynamicDatePicker', label: '日期时间', required: false, vModel: 'datetime' },{ type: 'DynamicUpload', label: '文件上传', required: false, vModel: 'c' },{ type: 'DynamicImageUpload', label: '图片上传', required: false, vModel: 'imageupload' },{type: 'DynamicSelect',label: '下拉选择',required: false,vModel: 'select',label: '选项',options: ['选项1', '选项2']},{type: 'DynamicCheckboxGroup',label: '多选框组',required: false,vModel: 'checkboxgroup',label: '多选',options: ['选项A', '选项B', '选项C']}],// availableComponents: [// { id: 1, label: '张三', type:'1', vModel:'' },// { id: 2, label: '李四', type:'2', vModel:'' }// ],// 当前设计的表单结构formStructure: [// { id: 3, label: '王五', type: '3', vModel:''},],// 表单数据模型formData: {},// 当前选中项selectedItem: null};},methods: {// 控件被添加到设计区时触发onComponentAdded(event) {// console.log('add:', event);const newComponent = this.formStructure[event.newIndex];// 动态添加 id 字段if (!newComponent.id) {newComponent.id = Date.now() + Math.random().toString(36).substring(2);}this.formData[newComponent.vModel] = '';this.selectedItem = newComponent;console.log('index:', event.newIndex, 'newComponent:', newComponent, newComponent.id);console.log('formStructure:', this.formStructure[event.newIndex]);},// 点击控件时更新右侧配置selectComponent(item) {this.selectedItem = item;},handleComponentClone(component) {console.log('component:', component);console.log('component.label:', component.label);// 创建副本,避免修改原始 availableComponents 中的数据const clone = cloneDeep(component);clone.id = Date.now() + Math.random().toString(36).substring(2);console.log('clone:', clone);console.log('clone.id:', clone.id);console.log('clone.type:', clone.type);console.log('clone.label:', clone.label);console.log('clone.vModel:', clone.vModel);return clone;},deepClone(parm) {let dataType = Object.prototype.toString.call(parm);let result;if (dataType === '[object Array]') {result = [];for (let i = 0; i < parm.length; i++) {result[i] = deepClone(parm[i]);}} else if (dataType === '[object Object]') {result = {};for (const key in parm) {if (Object.hasOwnProperty.call(parm, key)) {result[key] = deepClone(parm[key]);}}} else {result = parm;}return result;}}
};
</script><style scoped>
.form-designer {display: flex;height: 100vh;
}.component-panel,
.config-panel {width: 250px;padding: 10px;background-color: #f9f9f9;border-right: 1px solid #e4e4e4;
}.design-canvas {flex: 1;padding: 10px;overflow-y: auto;
}.component-item {padding: 8px;margin-bottom: 6px;background-color: #fff;border: 1px solid #ddd;cursor: move;text-align: center;
}.form-items {min-height: 100px;border: 1px dashed #ccc;padding: 10px;
}.form-item {border: 1px solid #eee;padding: 10px;margin-bottom: 10px;
}.form-item.selected {border-color: #409eff; /* Element UI 主色调 */box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.5); /* 可选:添加外发光效果 */
}
</style>
相关文章:

表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...
Python第七周作业
Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt,并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径,并创建logs目录(若不存在) 3.递归遍历目录data,输出所有.csv文件的路径…...

Qt的学习(二)
1. 创建Hello Word 两种方式,实现helloworld: 1.通过图形化的方式,在界面上创建出一个控件,显示helloworld 2.通过纯代码的方式,通过编写代码,在界面上创建控件, 显示hello world; …...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...

工厂方法模式和抽象工厂方法模式的battle
1.案例直接上手 在这个案例里面,我们会实现这个普通的工厂方法,并且对比这个普通工厂方法和我们直接创建对象的差别在哪里,为什么需要一个工厂: 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类: 两个发…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...

鸿蒙Navigation路由导航-基本使用介绍
1. Navigation介绍 Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(Nav…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
「Java基本语法」变量的使用
变量定义 变量是程序中存储数据的容器,用于保存可变的数据值。在Java中,变量必须先声明后使用,声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例:声明与初始化 public class VariableDemo {publi…...

CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...

ZYNQ学习记录FPGA(二)Verilog语言
一、Verilog简介 1.1 HDL(Hardware Description language) 在解释HDL之前,先来了解一下数字系统设计的流程:逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端,在这个过程中就需要用到HDL,正文…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...
6.计算机网络核心知识点精要手册
计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法:数据与控制信息的结构或格式,如同语言中的语法规则语义:控制信息的具体含义和响应方式,规定通信双方"说什么"同步:事件执行的顺序与时序…...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

五、jmeter脚本参数化
目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...

C++11 constexpr和字面类型:从入门到精通
文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...
python打卡day49@浙大疏锦行
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...