Vue3 + Element Plus 动态表单实现
完整代码
<template><div class="dynamic-form-container"><el-formref="dynamicFormRef":model="formData":rules="formRules"label-width="auto"label-position="top"v-loading="loading"><!-- 动态渲染表单字段 --><template v-for="field in formConfig" :key="field.name"><!-- 输入框 --><el-form-itemv-if="field.type === 'input'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><el-inputv-model="formData[field.name]":placeholder="field.placeholder || `请输入${field.label}`":type="field.inputType || 'text'":clearable="field.clearable !== false"/></el-form-item><!-- 下拉选择 --><el-form-itemv-else-if="field.type === 'select'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><el-selectv-model="formData[field.name]":placeholder="field.placeholder || `请选择${field.label}`":clearable="field.clearable !== false"style="width: 100%"><el-optionv-for="option in field.options":key="option.value":label="option.label":value="option.value"/></el-select></el-form-item><!-- 单选框 --><el-form-itemv-else-if="field.type === 'radio'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><el-radio-group v-model="formData[field.name]"><el-radiov-for="option in field.options":key="option.value":label="option.value">{{ option.label }}</el-radio></el-radio-group></el-form-item><!-- 复选框 --><el-form-itemv-else-if="field.type === 'checkbox'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><el-checkbox-group v-model="formData[field.name]"><el-checkboxv-for="option in field.options":key="option.value":label="option.value">{{ option.label }}</el-checkbox></el-checkbox-group></el-form-item><!-- 日期选择器 --><el-form-itemv-else-if="field.type === 'date'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><el-date-pickerv-model="formData[field.name]":type="field.dateType || 'date'":placeholder="field.placeholder || `请选择${field.label}`"style="width: 100%"/></el-form-item><!-- 开关 --><el-form-itemv-else-if="field.type === 'switch'":label="field.label":prop="field.name"><el-switch v-model="formData[field.name]" /></el-form-item><!-- 自定义插槽 --><el-form-itemv-else-if="field.type === 'slot'":label="field.label":prop="field.name":rules="generateFieldRules(field)"><slot :name="field.slotName" :field="field" :model="formData" /></el-form-item></template><el-form-item><el-button type="primary" @click="submitForm">提交</el-button><el-button @click="resetForm">重置</el-button></el-form-item></el-form></div>
</template><script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'// 表单引用
const dynamicFormRef = ref()// 加载状态
const loading = ref(false)// 表单数据
const formData = ref({})// 表单验证规则
const formRules = ref({})// 表单配置(从后端获取)
const formConfig = ref([// 默认配置,实际会被后端数据覆盖{name: 'username',label: '用户名',type: 'input',required: true,placeholder: '请输入用户名'}
])// 模拟从后端获取表单配置
const fetchFormConfig = async () => {try {loading.value = true// 这里替换为实际的API调用const response = await mockApiGetFormConfig()formConfig.value = response.data.fields// 初始化表单数据initFormData()// 生成验证规则generateFormRules()} catch (error) {ElMessage.error('获取表单配置失败: ' + error.message)} finally {loading.value = false}
}// 初始化表单数据
const initFormData = () => {const data = {}formConfig.value.forEach(field => {// 根据字段类型设置默认值switch (field.type) {case 'checkbox':data[field.name] = field.defaultValue || []breakcase 'switch':data[field.name] = field.defaultValue || falsebreakdefault:data[field.name] = field.defaultValue || ''}})formData.value = data
}// 生成表单验证规则
const generateFormRules = () => {const rules = {}formConfig.value.forEach(field => {if (field.required || field.rules) {rules[field.name] = generateFieldRules(field)}})formRules.value = rules
}// 生成单个字段的验证规则
const generateFieldRules = (field) => {const rules = []// 必填规则if (field.required) {rules.push({required: true,message: field.message || `${field.label}不能为空`,trigger: field.trigger || 'blur'})}// 自定义规则if (field.rules && Array.isArray(field.rules)) {rules.push(...field.rules)}// 类型校验if (field.type === 'input' && field.inputType === 'email') {rules.push({type: 'email',message: '请输入正确的邮箱格式',trigger: ['blur', 'change']})}return rules
}// 提交表单
const submitForm = async () => {try {// 表单验证await dynamicFormRef.value.validate()// 这里替换为实际的提交APIconst response = await mockApiSubmitForm(formData.value)ElMessage.success('提交成功')console.log('表单数据:', formData.value)console.log('服务器响应:', response)// 可以在这里处理提交成功后的逻辑} catch (error) {if (error instanceof Error) {ElMessage.error('表单验证失败: ' + error.message)}}
}// 重置表单
const resetForm = () => {dynamicFormRef.value.resetFields()
}// 模拟API获取表单配置
const mockApiGetFormConfig = () => {return new Promise((resolve) => {setTimeout(() => {resolve({data: {fields: [{name: 'username',label: '用户名',type: 'input',required: true,placeholder: '请输入用户名',maxlength: 20},{name: 'password',label: '密码',type: 'input',inputType: 'password',required: true,placeholder: '请输入密码',rules: [{ min: 6, max: 18, message: '密码长度在6到18个字符', trigger: 'blur' }]},{name: 'gender',label: '性别',type: 'select',required: true,options: [{ label: '男', value: 'male' },{ label: '女', value: 'female' },{ label: '其他', value: 'other' }]},{name: 'hobbies',label: '兴趣爱好',type: 'checkbox',options: [{ label: '游泳', value: 'swimming' },{ label: '跑步', value: 'running' },{ label: '阅读', value: 'reading' }]},{name: 'subscribe',label: '订阅通知',type: 'switch',defaultValue: true},{name: 'birthday',label: '出生日期',type: 'date',dateType: 'date',required: true}]}})}, 800)})
}// 模拟API提交表单
const mockApiSubmitForm = (data) => {return new Promise((resolve) => {setTimeout(() => {resolve({ code: 200, message: 'success', data })}, 500)})
}// 组件挂载时获取表单配置
onMounted(() => {fetchFormConfig()
})
</script><style scoped>
.dynamic-form-container {max-width: 800px;margin: 0 auto;padding: 20px;
}
</style>
后端API数据结构建议
后端API返回的表单配置建议采用如下JSON格式:
{"code": 200,"message": "success","data": {"fields": [{"name": "username","label": "用户名","type": "input","required": true,"placeholder": "请输入用户名","inputType": "text","maxlength": 20,"rules": [{"pattern": "^[a-zA-Z0-9_]+$","message": "只能包含字母、数字和下划线"}]},{"name": "gender","label": "性别","type": "select","required": true,"options": [{"label": "男","value": "male"},{"label": "女","value": "female"}]},{"name": "subscribe","label": "订阅通知","type": "switch","defaultValue": true}]}
}
相关文章:
Vue3 + Element Plus 动态表单实现
完整代码 <template><div class"dynamic-form-container"><el-formref"dynamicFormRef":model"formData":rules"formRules"label-width"auto"label-position"top"v-loading"loading"&g…...
【WPF】Opacity 属性的使用
在WPF(Windows Presentation Foundation)中,Opacity 属性是定义一个元素透明度的属性,其值范围是从 0.0(完全透明)到 1.0(完全不透明)。由于 Opacity 是在 UIElement 类中定义的&…...

Unity光照笔记
问题 在做项目中遇到了播放中切换场景后地面阴影是纯黑的问题,不得不研究一下光照。先放出官方文档。 Lighting 窗口 - Unity 手册 播放中切换场景后地面阴影是纯黑 只有投到地面的阴影是纯黑的。且跳转到使用相同Terrain的场景没有问题。 相关文章:…...
Linux中安装samba服务
在Linux服务器上安装Samba可以实现文件共享功能,下面为你详细介绍安装步骤: 一、安装Samba 不同的Linux发行版使用不同的命令来安装Samba: Debian/Ubuntu: sudo apt update sudo apt install sambaCentOS/RHEL: s…...
猫咪如厕检测与分类识别系统系列~进阶【三】网页端算法启动架构及数据库实现
前情提要 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如…...
Elasticsearch性能调优全攻略:从日志分析到集群优化
#作者:猎人 文章目录 前言搜索慢查询日志索引慢写入日志性能调优之基本优化建议性能调优之索引写入性能优化提升es集群写入性能方法:性能调优之集群读性能优化性能调优之搜索性能优化性能调优之GC优化性能调优之路由优化性能调优之分片优化 前言 es里面…...

嵌入式学习的第二十天-数据结构-调试+链表的一般操作
一、调试 1.一般调试 2.找段错误 二、链表的一般操作 1.单链表的修改 int ModifyLinkList(LinkList*ll,char*name,DATATYPE*data) {DATATYPE * tmp FindLinkList(ll, name);if(NULL tmp){return 1;}memcpy(tmp,data,sizeof(DATATYPE));return 0; } 2.单链表的销毁 int D…...
Leetcode 3548. Equal Sum Grid Partition II
Leetcode 3548. Equal Sum Grid Partition II 1. 解题思路2. 代码实现 题目链接:3548. Equal Sum Grid Partition II 1. 解题思路 这一题是题目3546. Equal Sum Grid Partition I的进阶版本,不过本质上还是差不多的。 相较于题目3546,这里…...

家具制造行业的现状 质检LIMS如何赋能家具制造企业质检升级
在家具制造行业,从原木切割到成品出厂,质检环节贯穿始终 —— 木材含水率是否达标、板材甲醛释放量是否合规、涂层耐磨性能否通过标准…… 这些看似琐碎的检测项目,实则是企业把控产品品质、规避市场风险的核心关卡。传统人工质检模式在效率、…...

idea整合maven环境配置
idea整合maven 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】:每个知识点,都是写出代码…...

无偿帮写毕业论文(看不懂的可以私信博主)
以下教程教你如何利用相关网站和AI免费帮你写一个毕业论文。毕竟毕业论文只要过就行,脱产学习这么多年,终于熬出头了,完成毕设后有空就去多看看亲人好友,祝好! 一、找一个论文模板 废话不多说,先上干货Ov…...

小白成长之路-vim编辑
文章目录 Vim一、命令模式二、插入模式3.a:进入插入模式,在当前光标的后一个字符插入4.o: 在当前光标的下一行插入5.i:在当前光标所在字符插入,返回命令模…...
Java 开源报表系统全解析:免费工具、企业案例与集成实践
在企业级数据可视化与报表开发中,选择一款功能强大且完全免费的开源报表系统至关重要。本文深度剖析 5 款经过权威验证的免费开源 Java 报表工具,涵盖图表展示、定制化及第三方集成能力,附企业级案例与技术实践,助您高效选型。 一…...

【常用算法:排序篇】7.算法魔法与面试秘籍:从趣味排序到实战通关
一、趣味排序算法:突破常规的思维火花 1. 睡眠排序(Sleep Sort)—— 时间维度的魔法 核心思想:利用多线程休眠时间模拟数值大小,自然输出有序结果。Python示例:import threading import timedef sleep_so…...
前端npm的核心作用与使用详解
一、npm是什么? npm(Node Package Manager) 是 Node.js 的默认包管理工具,也是全球最大的开源代码库生态系统。虽然它最初是为 Node.js 后端服务设计的,但如今在前端开发中已成为不可或缺的基础设施。通过npm,开发者可以轻松安装、管理和共享代码模块。 特性: 依赖管理…...

Android | IOS — Solox性能测试
文章目录 Solox性能测试1. 前置条件2. 软件图片 Solox性能测试 1. 前置条件 安装Python:3.10.0以上版本: Windows:Python官网 安装 SoloX python -m solox2. 软件图片 软件图片 报告分析:...
Rust 数据结构:Vector
Rust 数据结构:Vector Rust 数据结构:Vector创建数组更新数组插入元素删除元素 获取数组中的元素迭代数组中的值使用枚举存储多个类型删除一个数组会删除它的元素 Rust 数据结构:Vector vector 来自标准库,在内存中连续存储相同类…...
探索Turn.js:打造惊艳的3D翻页效果
目录 简介与特性 环境准备与安装 基础用法与初始化 配置参数详解 事件监听与交互 动态加载与页面管理 兼容性与性能优化 常见问题与解决方案 完整示例代码 1. 简介与特性 Turn.js 是一个基于 jQuery 的 JavaScript 库,专注于实现类书籍翻页的 3D 动画效果…...

Midjourney 最佳创作思路与实战技巧深度解析【附提示词与学习资料包下载】
引言 在人工智能图像生成领域,Midjourney 凭借其强大的艺术表现力和灵活的创作模式,已成为设计师、艺术家和创意工作者的核心工具。作为 CSDN 博主 “小正太浩二”,我将结合多年实战经验,系统分享 Midjourney 的创作方法论&#x…...
OPC UA + ABP vNext 企业级实战:高可用数据采集框架指南
🚀📊 OPC UA ABP vNext 企业级实战:高可用数据采集框架指南 🚀 📑 目录 🚀📊 OPC UA ABP vNext 企业级实战:高可用数据采集框架指南 🚀一、前言 🎯二、系统…...
MySQL库级管理:数据库管理与存储引擎剖析
引言 各位数据库爱好者们好!今天我们要深入探讨MySQL数据库的基本操作,这是每位开发者必须掌握的"内功心法" 💪。无论你是刚接触MySQL的小白,还是需要复习基础的老手,这篇教程都将带你系统学习数据库的核心…...
LeetCode 2094.找出 3 位偶数:遍历3位偶数
【LetMeFly】2094.找出 3 位偶数:遍历3位偶数 力扣题目链接:https://leetcode.cn/problems/finding-3-digit-even-numbers/ 给你一个整数数组 digits ,其中每个元素是一个数字(0 - 9)。数组中可能存在重复元素。 你…...
机器学习-计量经济学
机器学习 不要事前决定变量关系,关键是谁也不知道啊,机器学习学习的模型(那也不是真实的关系啊) 这就是自然学科的好处:只要不断的优化这个未知的东西(函数),然后在数据上ÿ…...

工具篇-扣子空间MCP,一键做游戏,一键成曲
一、登陆扣子空间 地址如下: 扣子空间 打开,然后登陆扣子 登陆之后快速开始: 二、生成游戏 小试牛刀,我们让它做一个打地鼠的游戏: 已经开始设计制作: 制作完成: 三、制作音乐 新…...

5.6 - 5.9 MySQL
数据库:存储和管理数据的仓库DB。 数据库管理系统:操纵和管理数据库的大型软件DBMS。 关系型数据库 一个数据库内可以创建多张表,在一个表内能存放多个数据。 SQL语句: DDL: 存储字符串用varchar。(类似于…...

C# WinForm 如何高效地将大量数据从 CSV 文件导入 DataGridView
如果你有非常多的csv文件,每个文件包含N多行与M多列,如:18000 行和 27 列。现在,想制作一个 Windows 窗体应用程序,导入它们并在 datagridview 中显示,然后进行一些数学运算。可是,发现数据导入…...
【redis】redis常见数据结构及其底层,redis单线程读写效率高于多线程的理解,
redis常用数据结构及底层 string字符串、list链表、set无序集合、zset有序集合、hash哈希 1.string 底层结构是SDS简单动态字符串 struct sdshdr {int len; // 已用长度(字符串实际长度)int free; // 剩余可用空间char buf[]; // 数组&#…...
2025年5月AI科技领域周报(5.5-5.11):AGI研究进入关键验证期 具身智能开启物理世界交互新范式
2025年5月AI科技领域周报(5.5-5.11):AGI研究进入关键验证期 具身智能开启物理世界交互新范式 一、本周热点回顾1. OpenAI发布GPT-5多模态大模型 突破通用智能关键阈值2. 特斯拉Optimus机器人量产版发布 具身智能进入工业场景3. 百度文心ERNIE…...

SQLPub:一个提供AI助手的免费MySQL数据库服务
给大家介绍一个免费的 MySQL 在线数据库环境:SQLPub。它提供了最新版本的 MySQL 服务器测试服务,可以方便开发者和测试人员验证数据库功能,也可以用于学习 MySQL。 免费申请 在浏览器中输入以下网址: https://sqlpub.com/ SQLP…...

URP相机如何将场景渲染定帧模糊绘制
1)URP相机如何将场景渲染定帧模糊绘制 2)为什么Virtual Machine会随着游戏时间变大 3)出海项目,打包时需要勾选ARMv7吗 4)Unity是手动还是自动调用GC.Collect 这是第431篇UWA技术知识分享的推送,精选了UWA社…...