基于uni-app的动态表单

news2024/12/24 20:16:03

一、应用场景和意义

可以通过配置字段和校验规则,快速完成页面开发、提升开发效率

二、应用前提

形成ui/业务规范,最好是应用在问卷调查之类的业务

三、动态表单的功能

字段报错、快速滚动定位报错信息、支持字段值和字段规则拆分,便于实现复杂的表单交互

四、动态表单支持的组件类型

1、input-text 文本输入框类型

<template v-if="item.type === 'input-text'">

<view class="formItemBox">

<view class="formItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

<view class="right">

<u-form-item>

<view v-if="item.readonly || disabledFields.includes(item.id)"

@click="showNoEdit" class="readonlytext">{{ form[item.id] }}

</view>

<u--input v-else style="width: 100%;" v-model="form[item.id]"

input-align="right" :placeholder="item.placeholder"

:placeholderStyle="placeholderStyle"

border="none"></u--input>

</u-form-item>

</view>

</view>

<u-form-item labelWidth="0" :prop="item.id" class="formItemNoBody">

</u-form-item>

<view class="line" v-show="formItem.list.length - 1 > index"></view>

</view>

</template>

支持正常的输入校验 和 不可编辑的样式和提示

2、single-select 单选

<template v-if="item.type === 'single-select'">

<view class="formItemBox">

<view class="formItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

<view class="right optItemBox">

<view class="optItem" @click.stop="showNoEditOrSelect(item)"></view>

<u-form-item>

<view v-if="item.readonly || disabledFields.includes(item.id)"

class="readonlytext">{{ form[item.id] }}</view>

<view v-else class="select_right">

<view v-if="!form[item.id]" class="placeholderStyle">

{{ item.placeholder }}</view>

<view v-else class="select_right_text">

{{ item.listMap[form[item.id]] &&

item.listMap[form[item.id]].name || '未匹配到' }}

</view>

</view>

<view v-show="false">

<u--input style="width: 100%;" v-model="form[item.id]"

input-align="right" :placeholder="item.placeholder"

:placeholderStyle="placeholderStyle"

border="none"></u--input>

</view>

<view class="arrow_right_icon">

<img src="./icon/arrow.png" alt="">

</view>

</u-form-item>

</view>

</view>

<u-form-item labelWidth="0" :prop="item.id" class="formItemNoBody">

</u-form-item>

<view class="line"></view>

</view>

<!-- <u-action-sheet cancelText="取消" :safeAreaInsetBottom="true" :actions="item.list"

:title="item.selectTitle" safeAreaInsetBottom :show="item.showSelect"

@select="selectConfirm($event, item)" @close="selectClose(item)"></u-action-sheet> --> <u-picker :show="item.showSelect" ref="uPicker" :defaultIndex="defaultIndex" :confirmColor="env.themeColor" :columns="[item.list]" @cancel="selectClose(item)" @close="selectClose(item)" keyName="name" @confirm="selectConfirm($event, item)"></u-picker>

</template>

支持正常的单选和不可编辑以及未匹配到的提示

3、dependent-computing 依赖别的字段计算

<template v-if="item.type === 'dependent-computing'">

<view class="formItemBox">

<view class="formItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

<view class="right optItemBox">

<view class="optItem" @click.stop="showNoEditOrSelect(item)"></view>

<u-form-item>

<view v-if="item.readonly || disabledFields.includes(item.id)"

class="readonlytext">{{ form[item.id] }}</view>

<view v-else class="select_right">

<u--input style="width: 100%;" v-model="form[item.id]"

input-align="right" :placeholder="item.placeholder"

:placeholderStyle="placeholderStyle"

border="none"></u--input>

</view>

</u-form-item>

</view>

</view>

<u-form-item labelWidth="0" :prop="item.id" class="formItemNoBody">

</u-form-item>

<view class="line"></view>

</view>

</template>

依赖计算不可编辑、做显示

4、switch 开关

<template v-if="item.type === 'switch'">

<view class="formItemBox">

<view class="formItem formSwitchItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

<view class="right optItemBox">

<view v-if="item.readonly || disabledFields.includes(item.id)"

class="optItem" @click.stop="showNoEditOrSelect(item)"></view>

<u-form-item>

<view class="switchBox">

<u-switch v-model="form[item.id]"

inactiveColor="rgba(229, 230, 235, 1)"

:activeColor="env.themeColor"

@change="changeSwitch($event, item)"></u-switch>

</view>

</u-form-item>

</view>

</view>

<u-form-item labelWidth="0" :prop="item.id" class="formItemNoBody">

</u-form-item>

<view class="line"></view>

</view>

</template>

5、单选日期 single-calendar

<template v-if="item.type === 'single-calendar'">

<view class="formItemBox">

<view class="formItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

<view class="right optItemBox">

<view class="optItem" @click.stop="showNoEditOrCalendar(item)">

</view>

<u-form-item>

<view v-if="item.readonly || disabledFields.includes(item.id)"

class="readonlytext">{{ form[item.id] }}</view>

<view v-else class="select_right">

<view v-if="!form[item.id]" class="placeholderStyle">

{{ item.placeholder }}</view>

<view v-else class="select_right_text">

{{ form[item.id] }}</view>

</view>

<view v-show="false">

<u--input style="width: 100%;" v-model="form[item.id]"

input-align="right" :placeholder="item.placeholder"

:placeholderStyle="placeholderStyle"

border="none"></u--input>

</view>

<view class="arrow_right_icon">

<img src="./icon/arrow.png" alt="">

</view>

</u-form-item>

</view>

</view>

<u-form-item labelWidth="0" :prop="item.id" class="formItemNoBody">

</u-form-item>

<view class="line"></view>

</view>

<!-- <u-calendar :show="item.showSingleCalendar" :color="env.themeColor"

:defaultDate="defaultDateSingle" mode="single"

></u-calendar> -->

<u-datetime-picker :show="item.showSingleCalendar" v-model="defaultDateSingle"

mode="date" @confirm="singleCalendarConfirm($event, item)"

@cancel="closeCalendar(item)"

@close="closeCalendar(item)"></u-datetime-picker>

</template>

支持正常的单选和不可编辑

6、upload-images 上传图片

<template v-if="item.type === 'upload-images'">

<view class="formItemBox">

<view class="formItem">

<view class="left">

<view class="num" v-if="num">{{ index + 1 }}.</view>

<view v-if="item.redTip" class="colorRed">{{ item.redTip ? '*' : ''

}}

</view>

<view class="name">{{ item.label }}</view>

</view>

</view>

<view class='img-wrap'>

<view v-show="false">

<u--input style="width: 100%;" v-model="form[${item.id}filePath]"

input-align="right" :placeholder="item.placeholder"

:placeholderStyle="placeholderStyle" border="none"></u--input>

</view>

<Upload :filesData="form[item.id] || []"

@onFilesChange="(items) => filesDataChange(items, ${item.id})"

:disableEdit="item.readonly || disabledFields.includes(item.id)"

:max='item.imgLen' uploadType='photo' />

</view>

<u-form-item labelWidth="0" :prop="${item.id}filePath"

class="formItemNoBody">

</u-form-item>

<view class="line"></view>

</view>

</template>

这个图片上传耦合了接口上传 和禁止编辑

五、入参

formData 表单校验规则

valueForm 表单字段值

六、使用示例

form: {

ownerName: '',

idNumbe: '',

phoneNumber: "",

proAddres: "",

projectDetailedAddress: "",

},

allFormData: [

{

title: '客户信息',

showTitle: true,

list: [{

id: "ownerName",

placeholder: "请输入",

label: "姓名",

type: "input-text",

redTip: false,

readonly: true,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}

]

},

{

id: "idNumbe",

placeholder: "请输入",

label: "证件号码",

type: "input-text",

redTip: false,

readonly: true,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}

]

},

{

id: "phoneNumber",

placeholder: "请输入",

label: "联系电话",

type: "input-text",

redTip: false,

readonly: true,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}

]

},

]

},

{

title: '项目地址',

showTitle: true,

list: [{

id: "proAddres",

placeholder: "请输入",

label: "项目地址",

type: "input-text",

redTip: false,

readonly: true,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}

]

}, {

id: "projectDetailedAddress",

placeholder: "请输入",

label: "详细地址",

type: "input-text",

redTip: false,

readonly: true,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}

]

}]

},

{

title: '电站基本情况',

showTitle: true,

list: [{

id: "zuKuai",

placeholder: "请输入",

label: "板块数",

type: "input-text",

redTip: false,

readonly: false,

rules: [

{

type: 'string',

required: true,

message: '请输入',

trigger: ['change', 'blur']

}, {

validator: (rule, value, callback) => {

const pattern = /^[1-9]\d{0,3}$|^[1-9]\d{0,3}$|^\d{1,4}$/

if (!pattern.test(value)) {

callback(new Error('请输入大于0小于10000的正整数'));

} else {

callback();

}

},

trigger: ['change', 'blur'],

}

]

},

{

id: "zuPower",

placeholder: "请选择",

label: "功率",

type: "single-select",

redTip: false,

readonly: false,

showSelect: false,

selectTitle: "请选择",

list: [],

listMap: {},

rules: [

{

type: 'string',

required: true,

message: '请选择',

trigger: ['change', 'blur']

}

]

},

{

id: "totalZuPower",

placeholder: "计算带出,不得修改",

label: "系统容量",

type: "dependent-computing",

redTip: false,

readonly: false,

rules: [{

type: 'string',

required: true,

message: '请完善版块数和功率',

trigger: ['change', 'blur']

}, {

validator: (rule, value, callback) => {

if (Number(value) > 120000) {

callback(new Error('系统容量不能大于120000'));

} else {

callback();

}

},

trigger: ['change', 'blur'],

}]

},]

},

{

title: '付款信息',

showTitle: true,

list: [

{

id: "priceType",

placeholder: "请选择",

label: "价格类型",

type: "single-select",

redTip: false,

readonly: false,

showSelect: false,

selectTitle: "请选择",

list: [],

listMap: {},

rules: [

{

type: 'string',

required: true,

message: '请选择',

trigger: ['change', 'blur']

}

],

beferConfirmFun: (confirmFun) => {

uni.showModal({

title: '提示',

content: '修改价格类型后需重新填写付款信息',

success: async (res) => {

if (res.confirm) {

confirmFun()

}

},

});

}

},

{

id: "assemblyAttribute",

placeholder: "请选择",

label: "组件属性",

type: "single-select",

redTip: false,

readonly: false,

showSelect: false,

selectTitle: "请选择",

list: [],

listMap: {},

rules: [

{

type: 'string',

required: true,

message: '请选择',

trigger: ['change', 'blur']

}

]

},

{

id: "applySituation",

placeholder: "请选择",

label: "应用场景",

type: "single-select",

redTip: false,

readonly: false,

showSelect: false,

selectTitle: "请选择",

list: [],

listMap: {},

rules: [

{

type: 'string',

required: true,

message: '请选择',

trigger: ['change', 'blur']

}

]

},

{

id: "singleDoubleSide",

placeholder: "请选择",

label: "单双面",

type: "single-select",

redTip: false,

readonly: false,

showSelect: false,

selectTitle: "请选择",

list: [],

listMap: {},

rules: [

{

type: 'string',

required: true,

message: '请选择',

trigger: ['change', 'blur']

}

]

},

]

},

],

七、案例显示

可以进行复杂的交互和可视区域定位校验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1621608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《R语言与农业数据统计分析及建模》学习——描述性统计分析

一、描述性统计概念和方法 1、概念和作用 描述性统计是对数据进行概括和描述&#xff0c;便于理解数据的特征、趋势和分布&#xff0c;帮助我们了解数据基本情况和总体特征&#xff0c;为后续更深入的数据分析和建模提供基础。 2、基础方法 &#xff08;1&#xff09;中心趋…

STM32的定时器

一、介绍 定时器的工作原理 通用定时器的介绍 定时器的计数模式 定时器时钟源 定时器溢出时间计算公式 二、使用定时器中断点亮LED灯 打开一个LED灯 更改TIME2 然后就是生成代码 三&#xff0c;代码

深度学习基础之《TensorFlow框架(15)—神经网络》

一、神经网络基础 1、什么是神经网络 人工神经网络&#xff08;Artificial Neural Network&#xff0c;简写为ANN&#xff09;。也简称为神经网络&#xff08;NN&#xff09; 是一种模仿生物神经网络&#xff08;动物的中枢神经系统&#xff0c;特别是大脑&#xff09;结构和功…

网络安全与密码学--AES加密

分组加密之AES加密算法 AES算法的诞生 python实现AES加密 AES加密详细流程 AES解密过程 AES的应用 1997年 NIST征集AES&#xff08;Advanced Encryption Standard&#xff09;2000年选中 https://www.nist.gov/ https://csrc.nist.gov/projects/block-cipher-techniques A…

WPForms Pro插件下载:简化您的在线表单构建,提升用户互动

在当今的数字化世界中&#xff0c;表单是网站与用户互动的关键。无论是收集信息、处理订单还是进行调查&#xff0c;一个好的表单可以极大地提升用户体验和转化率。WPForms Pro插件&#xff0c;作为一款专业的WordPress表单构建工具&#xff0c;旨在帮助您轻松创建美观、功能强…

如何求候选码、属性集的闭包

目录 一、基础理论 二、属性集的闭包 三、四类 四、例题 基础理论部分是我的异想天开&#xff0c;可跳过。 一、基础理论 数据库注重于研究关系&#xff0c;谈起关系&#xff0c;那么不得不提起《离散数学》&#xff0c;起初我认为求候选码的过程一定暗合《离散数学》中的…

【JavaScript】axios

基础使用 <script src"https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.min.js"></script> <script>axios.get(https://study.duyiedu.com/api/herolist).then(res> {console.log(res.data)}) </script>get - params <script s…

《智能前沿:应对ChatGPT算力挑战》

在全球人工智能热潮中&#xff0c;以 ChatGPT 为代表的 AIGC 技术引发了广泛关注。人工智能和机器学习等技术对数据规模及处理速度等提出了更高要求。在数据成为主要生产要素的当下和未来&#xff0c;如何跟上时代的发展步伐&#xff0c;构建适应 AI 需求的数据中心&#xff0c…

树莓派驱动开发----iic驱动oled屏幕篇

水一期吧&#xff0c;上效果 有点模糊&#xff0c;我直接说吧&#xff0c;修改设备树&#xff0c;iic1&#xff0c;地址0x3c&#xff0c;然后编写驱动文件&#xff0c;app文件&#xff0c;挂载驱动模块后在终端输入 /*******************************************************…

Bayes判别:统计学中的经典分类方法

在统计和机器学习领域&#xff0c;Bayes判别是一个基于概率理论的强大工具&#xff0c;用于解决分类问题。它基于Bayes定理&#xff0c;通过计算和比较后验概率来进行决策。这种方法在处理不确定性和不完整数据时表现尤为出色&#xff0c;因此在医学诊断、邮件过滤、语音识别等…

python绘制R控制图(Range Chart)

R控制图&#xff08;Range Chart&#xff09;&#xff0c;也称为范围图或移动极差图&#xff0c;是一种用于分析和控制生产过程中的变异性的统计工具。它通常与Xbar控制图&#xff08;均值图&#xff09;一起使用&#xff0c;可以提供关于生产过程变异性的额外信息。以下是R控制…

恶意软件狩猎新途径:使用.NET元数据分析跟踪恶意软件

本文由Blaze于2024年3月25日发表于其个人博客网站上。 就在不久前&#xff0c;我们意外发现了一个PureCrypter样本&#xff0c;而PureCrypter则是一款适用于各种类型恶意软件&#xff08;例如Agent Tesla和RedLine&#xff09;的加载器和混淆处理工具。深入分析之后&#xff0c…

文章杂记 | C++动态内存分配

1、C类和动态内存分配 https://blog.csdn.net/u011381222/article/details/137734622 Stringbad.h #pragma once #ifndef STRINGBAD_ #define STRINGBAD_#include<iostream>using namespace std;class Stringbad { private:char* str;//字符串地址int len; //长度st…

前端三剑客 HTML+CSS+JavaScript ④ HTML标签

祝你先于春天&#xff0c;翻过此间铮铮山峦 —— 24.4.23 一、HTML排版标签 1.标题标签 h1~h6 标签含义&#xff1a;标题 单/双标签&#xff1a;双 主要用前三个 2.段落标签 p 标签含义&#xff1a;段落 单/双标签&#xff1a;双 3.div 没有任何含…

Day17-Java进阶-网络编程(IP, 端口, 协议)TCP和UDP三次握手和四次挥手

1. 网络编程介绍 1.1 初始网络编程 1.2 网络编程三要素 1.2.1 IP InetAddress 的使用 package com.itheima.Inetaddress;import java.net.InetAddress; import java.net.UnknownHostException;public class InetAddressDemo1 {/*static InetAddress getByName(String host) 确…

Redis分布式锁 - 基于Jedis和LUA的分布式锁

先基于单机模式&#xff0c;基于Jedis手工造轮子实现自己的分布式锁。 首先看两个命令&#xff1a; Redis 分布式锁机制&#xff0c;主要借助 setnx 和 expire 两个命令完成。 setnx命令: setnx 是 set if not exists 的简写。将 key 的值设为 value &#xff0c;当且仅当…

基于PaddlePaddle平台训练物体分类——猫狗分类

学习目标&#xff1a; 在百度的PaddlePaddle平台训练自己需要的模型&#xff0c;以训练一个猫狗分类模型为例 PaddlePaddle平台&#xff1a; 飞桨&#xff08;PaddlePaddle&#xff09;是百度开发的深度学习平台&#xff0c;具有动静统一框架、端到端开发套件等特性&#xf…

Mac装虚拟机好不好 Mac装虚拟机和装Windows系统一样吗 PD虚拟机

随着跨系统操作的不断发展&#xff0c;虚拟机技术在生产力领域扮演着越来越重要的角色。Mac作为一款主流的操作系统&#xff0c;也有着运行虚拟机的能力。接下来给大家介绍Mac装虚拟机好不好&#xff0c;Mac装虚拟机和装Windows系统一样吗的具体内容。 一、Mac装虚拟机好不好 …

直接用表征还是润色改写?LLM用于文生图prompt语义增强的两种范式

直接用表征还是润色改写&#xff1f;LLM用于文生图prompt语义增强的两种范式 导语 目前的文生图模型大多数都是使用 CLIP text encoder 作为 prompt 文本编码器。众所周知&#xff0c;由于训练数据是从网络上爬取的简单图文对&#xff0c;CLIP 只能理解简单语义&#xff0c;而…

linux文件句柄数满,linux文件句柄数超出系统限制怎么办?

1、问题阐述&#xff1a; too many open files&#xff1a;顾名思义即打开过多文件数。 不过这里的files不单是文件的意思&#xff0c;也包括打开的通讯链接(比如socket)&#xff0c;正在监听的端口等等&#xff0c;所以有时候也可以叫做句柄(handle)&#xff0c;这个错误通常…