当前位置: 首页 > news >正文

vue2+ant-design-vue a-form-model组件二次封装(form表单组件)FormModel 表单

一、效果图

在这里插入图片描述

二、参数配置

1、代码示例

<t-antd-form:ref-obj.sync="formOpts.ref":formOpts="formOpts":widthSize="1":labelCol="{ span:2}":wrapperCol="{ span:22}"@handleEvent="handleEvent"
/>

2. 配置参数继承FormModel的所有属性

参数说明类型默认值
refObjform 表单校验规则方法 (可以参考 antd FormModel 表单方法中的 validate)obj-
className自定义类名String-
layout改变表单项 label 与输入框的布局方式(默认:horizontal) /verticalString‘horizontal’
widthSize每行显示几个输入项(默认两项) 最大值 4Number2
isTrim全局是否开启清除前后空格(comp 为 a-input 且 type 不等于’password’)Booleantrue
formOpts表单配置项Object{}
—listTypeInfo下拉选择数据源(type:'select’有效)Object{}
—fieldListform 表单每项 listArray[]
------isHideItem某一项不显示Booleanfalse
------slotName自定义表单某一项输入框slot-
------childSlotName自定义表单某一下拉选择项子组件插槽(a-select-option)slot-
------compform 表单每一项组件是输入框还是下拉选择等(可使用第三方 UI 如 a-select/a-input 也可以使用自定义组件)String-
------formItemBind表单每一项属性(继承FormModelItem的 Attributes)Object{}
------bind表单每一项属性(继承第三方 UI 的 Attributes,如 a-input 中的 allowClear 清空功能)默认清空及下拉过滤Object{}
------isTrim是否不清除前后空格(comp 为 a-input 且 type 不等于’password’)Booleanfalse
------typeform 表单每一项类型String-
------widthSizeform 表单某一项所占比例(如果占一整行则设置 1)Number2
------widthform 表单某一项所占实际宽度String100%
------arrLabeltype=select-arr 时,每个下拉显示的中文String‘label’
------arrKeytype=select-arr 时,每个下拉显示的中文传后台的数字String‘value’
------labelform 表单每一项 titleString-
------labelRender自定义某一项 titlefunction-
------valueform 表单每一项传给后台的参数String-
------rules每一项输入框的表单校验规则Object/Array-
------list下拉选择数据源(仅仅对 type:'select’有效)String-
------event表单每一项事件标志(handleEvent 事件)String-
------eventHandle继承 comp 组件的事件(返回两个参数,第一个自己自带,第二个 formOpts)Object-
------isSelfCom是否使用自己封装的组件(TAntdSelect等—含有下拉框)Booleanfalse
—formData表单提交数据(对应 fieldList 每一项的 value 值)Object-
—labelCollabel 宽度({ span:2})Object{span:2}
—wrapperCol输入框 宽度Object{span:22}
—rules规则(可依据 AntdUI FormModel 配置————对应 formData 的值)Object/Array-
—operatorList操作按钮 listArray-

3. events继承FormModel的所有事件

事件名说明返回值
handleEvent单个查询条件触发事件fieldList 中 type/查询条件输入的值/fieldList 中 event 值

4. Methods

事件名说明参数
resetFields重置表单-
clearValidate清空校验-

5. 关于 Ant-Design-Vue FormModel/FormModelItem 提供的一些属性可直接使用,无需其他配置

三、源码

<template><FormModelref="form"class="t_antd_form":class="className":model="formOpts.formData":rules="formOpts.rules":layout="formOpts.layout||'horizontal'"v-bind="formAttr"v-on="$listeners"><template v-for="(item, index) in fieldList"><FormModelItemv-if="!item.isHideItem":key="index":prop="item.value":label="item.label":class="[item.className]":rules="item.rules":style="getChildWidth(item)"v-bind="{...item.formItemBind}"><!-- 自定义label --><template #label v-if="item.labelRender"><render-comp :createElementFunc="item.labelRender" /></template><!-- 自定义输入框插槽 --><template v-if="item.slotName"><slot :name="item.slotName"></slot></template><!-- 文本展示值 --><template v-if="item.textShow"><span>{{item.textValue||formOpts.formData[item.value]}}</span></template><template v-if="item.isSelfCom"><component:is="item.comp"v-model="formOpts.formData[item.value]":placeholder="item.placeholder||getPlaceholder(item)"v-bind="{allowClear:true,showSearch:true,...item.bind}":style="{width: item.width||'100%'}"v-on="cEvent(item)"/></template><componentv-if="!item.slotName&&!item.textShow&&!item.isSelfCom":is="item.comp"v-model="formOpts.formData[item.value]":type="item.type||item.bind.type":mode="item.comp.includes('picker')?(item.type||item.bind.type):''":placeholder="item.placeholder||getPlaceholder(item)"@change="handleEvent(item.event, formOpts.formData[item.value],item)"v-bind="{allowClear:true,showSearch:true,...item.bind}":style="{width: item.width||'100%'}"v-on="cEvent(item)"><template #addonBefore v-if="item.addonBefore">{{ item.addonBefore }}</template><template #addonAfter v-if="item.addonAfter">{{ item.addonAfter }}</template><template v-if="item.childSlotName"><slot :name="item.childSlotName"></slot></template><componentv-else:is="compChildName(item)"v-for="(value, key, index) in selectListType(item)":key="index":disabled="value.disabled":label="compChildLabel(item,value)":value="compChildValue(item,value,key)">{{compChildShowLabel(item,value)}}</component></component></FormModelItem></template><!-- 按钮 --><div class="footer_btn"><template v-if="formOpts.btnSlotName"><slot :name="formOpts.btnSlotName"></slot></template><template v-if="!formOpts.btnSlotName&&formOpts.operatorList&&formOpts.operatorList.length>0"><Buttonv-for="(val,index) in formOpts.operatorList":key="index"@click="val.fun(val)":type="val.type||'primary'":icon="val.icon":size="val.size || 'default'":disabled="val.disabled">{{ val.label }}</Button></template></div></FormModel>
</template>
<script>
import RenderComp from './render-comp.vue'
import { FormModel, Button } from 'ant-design-vue'
export default {name: 'TAntdForm',components: {RenderComp,FormModel,FormModelItem: FormModel.Item,Button},props: {/** 表单配置项说明* formData object 表单提交数据* rules object 验证规则* fieldList Array 表单渲染数据* operatorList Array 操作按钮list* listTypeInfo object 下拉选项数据*/formOpts: {type: Object,default: () => ({})},// 自定义类名className: {type: String},// 一行显示几个输入项;最大值4widthSize: {type: Number,default: 2,validator: (value) => {return value <= 4}},// 全局是否开启清除前后空格isTrim: {type: Boolean,default: true},// refrefObj: {type: Object}},data() {return {colSize: this.widthSize,fieldList: this.formOpts.fieldList}},computed: {formAttr() {let attr = {}this.formOpts.layout === 'vertical'? attr = {...this.$attrs} : attr = {labelCol: { span: 2 },wrapperCol: { span: 22 },...this.$attrs}return attr},cEvent() {return ({ eventHandle }, type) => {let event = { ...eventHandle }let changeEvent = {}Object.keys(event).forEach(v => {changeEvent[v] = (e, ids) => {if (type === 't-antd-select-table') {event[v] && event[v](e, ids, arguments)} else {if ((typeof e === 'number' && e === 0) || e) {event[v] && event[v](e, this.formOpts, arguments)} else {event[v] && event[v](this.formOpts, arguments)}}}})return { ...changeEvent }}},selectListType() {return ({ list }) => {if (this.formOpts.listTypeInfo) {return this.formOpts.listTypeInfo[list]} else {return []}}},// 子组件名称compChildName() {return ({ type }) => {switch (type) {case 'checkbox':return 'a-checkbox'case 'radio':return 'a-radio'case 'select-arr':case 'select-obj':return 'a-select-option'}}},// 子子组件labelcompChildLabel() {return ({ type, arrLabel }, value) => {switch (type) {case 'radio':case 'checkbox':return value.valuecase 'select-arr':return value[arrLabel || 'label']case 'select-obj':return value}}},// 子子组件valuecompChildValue() {return ({ type, arrKey }, value, key) => {switch (type) {case 'radio':case 'checkbox':return value.valuecase 'select-arr':return value[arrKey || 'value']case 'select-obj':return key}}},// 子子组件文字展示compChildShowLabel() {return ({ type, arrLabel }, value) => {switch (type) {case 'radio':case 'checkbox':return value.labelcase 'select-arr':return value[arrLabel || 'label']case 'select-obj':return value}}}},watch: {'formOpts.formData': {handler(val) {// 将form实例返回到父级this.$emit('update:refObj', this.$refs.form)},deep: true // 深度监听},widthSize(val) {if (val > 4) {this.$message.warning('widthSize值不能大于4!')this.colSize = 4} else {this.colSize = val}}},mounted() {// 将form实例返回到父级this.$emit('update:refObj', this.$refs.form)},methods: {// label与输入框的布局方式getChildWidth(item) {if (this.formOpts.layout === 'vertical') {return `flex: 0 1 calc((${100 / (item.widthSize || this.colSize)}% - 10px));margin-right:10px;`} else {return `flex: 0 1 ${100 / (item.widthSize || this.colSize)}%;`}},// 得到placeholder的显示getPlaceholder(row) {let placeholderif (typeof row.comp === 'string' && row.comp) {if (row.comp.includes('input')) {placeholder = row.label ? `请输入${row.label}` : `请输入`} else if (row.comp.includes('select') || row.comp.includes('cascader')) {placeholder = row.label ? `请选择${row.label}` : `请选择`} else if (!row.comp.includes('t-antd-date-picker')) {placeholder = row.label}} else {placeholder = row.label}return placeholder},// 绑定的相关事件handleEvent(type, val, item) {// console.log('组件', type, val, item)// 去除前后空格if (this.isTrim && !item.isTrim && item.comp.includes('input') && item.type !== 'password' && item.type !== 'inputNumber') {this.formOpts.formData[item.value] = this.formOpts.formData[item.value].trim()}this.$emit('handleEvent', type, val)},validate() {// selfValidate() {return new Promise((resolve, reject) => {this.$refs.form.validate(valid => {if (valid) {resolve({valid,formData: this.formOpts.formData})} else {// eslint-disable-next-line prefer-promise-reject-errorsreject({valid,formData: null})}})})},// 重置表单resetFields() {return this.$refs.form.resetFields()},// 清空校验clearValidate() {return this.$refs.form.clearValidate()}}
}
</script>
<style lang="scss">
.t_antd_form {display: flex;flex-wrap: wrap;.ant-select,.ant-calendar-picker {width: 100%;}.footer_btn {display: flex;align-items: center;justify-content: center;margin-top: 5px;width: 100%;.ant-btn {margin-left: 10px;}.ant-btn:first-child {margin-left: 0;}}
}
</style>

四、组件地址

gitHub组件地址

gitee码云组件地址

五、相关文章

基于ElementUi再次封装基础组件文档


基于ant-design-vue再次封装基础组件文档


vue3+ts基于Element-plus再次封装基础组件文档

相关文章:

vue2+ant-design-vue a-form-model组件二次封装(form表单组件)FormModel 表单

一、效果图 二、参数配置 1、代码示例 <t-antd-form:ref-obj.sync"formOpts.ref":formOpts"formOpts":widthSize"1":labelCol"{ span:2}":wrapperCol"{ span:22}"handleEvent"handleEvent" />2. 配置参数…...

对比解析php和go对JSON处理的区别

一、go 转化php数组代码 php程序 $str <<<EOF {"操作源":"任意","数据库":"任意","语句类型":"CREATE DATABASE&#xff1b;DROP DATABASE&#xff1b;ALTER DATABASE","影响行数":"不…...

HTTP和HTTPS本质区别——SSL证书

HTTP和HTTPS是两种广泛使用的协议&#xff0c;尽管它们看起来很相似&#xff0c;但是它们在网站数据传输的安全性上有着本质上的区别。 HTTP是明文传输协议&#xff0c;意味着通过HTTP发送的数据是未经加密的&#xff0c;容易受到拦截、窃听和篡改的风险。而HTTPS通过使用SSL或…...

JS 防抖和节流

防抖&#xff08;debounce&#xff09;和节流&#xff08;throttle&#xff09;是JavaScript中常用的性能优化技术&#xff0c;用于限制某些高频率触发的函数执行次数&#xff0c;减少不必要的计算和网络请求。下面分别介绍防抖和节流的实现方式。 防抖&#xff08;Debounce&am…...

Django开发实例总结(入门级、4.2.6、详细)

目录 概述 Django的核心组件包括 Django的项目结构 创建工程&#xff08;4.2.6&#xff09; 实例一&#xff1a;Hello world 实例二&#xff1a;访问一个自定义主页 实例三&#xff1a;通过登录跳转到主页 实例四&#xff1a;主页添加静态文件&#xff0c;包含js、css、…...

Variations-of-SFANet-for-Crowd-Counting可视化代码

前文对Variations-of-SFANet-for-Crowd-Counting做了一点基础梳理&#xff0c;链接如下&#xff1a;Variations-of-SFANet-for-Crowd-Counting记录-CSDN博客 本次对其中两个可视化代码进行梳理 1.Visualization_ShanghaiTech.ipynb 不太习惯用jupyter notebook, 这里改成了p…...

所有的人机交互都存在不匹配现象

从接受理论的角度来看&#xff0c;就像夫妻一样&#xff0c;所有的人机交互都存在不匹配的现象。 接受理论是一个解释人们如何学习和接受信息的心理模型。该理论认为&#xff0c;当人们学习新信息时&#xff0c;他们会将其与自己已有的知识和经验联系起来&#xff0c;以便更好地…...

LED数码管的静态显示与动态显示(Keil+Proteus)

前言 就是今天看了一下书上的单片机实验&#xff0c;发现很多的器件在Proteus中都不知道怎么去查找&#xff0c;然后想做一下这个实验&#xff0c;尝试能不能实现&#xff0c;LED数码管的两个还可以实现&#xff0c;但是用LED点阵显示器的时候他那个网络标号不知道是什么情况&…...

webGL编程指南 第五章 TexturedQuad_Clamp_Mirror

我会持续更新关于wegl的编程指南中的代码。 当前的代码不会使用书中的缩写&#xff0c;每一步都是会展开写。希望能给后来学习的一些帮助 git代码地址 &#xff1a;空 上一章节中我们学习了如何使用varyting变量绘制图片&#xff0c;本章节&#xff0c;我们学习texParameter…...

【Azure】存储服务:Azure 的存储账户

文章目录 一、前提知识&#xff08;建议了解&#xff09;二、介绍 Azure 存储帐户三、使用 Microsoft Azure 门户创建存储帐户 一、前提知识&#xff08;建议了解&#xff09; 在每一个云厂商中&#xff0c;都有自身的云存储&#xff0c;也有根据不同功能进行区分的不同类型的…...

高等数学啃书汇总重难点(十一)曲线积分与曲面积分

依旧是公式极其复杂恶心的一章&#xff0c;建议是&#xff1a;掌握两种线面积分的计算套路即可&#xff0c;和第8章一样属于同济版教材中最不重要的章节&#xff0c;不会对底层理解做过多考察~ 1.弧长曲线积分的几何意义 2.弧长曲线积分的定义和性质 3.弧长曲线积分的计算方式 …...

【算法专题】双指针—盛最多水的容器

一、题目解析 分析这个题目不难得出一个容积公式 二、算法原理 解法一&#xff1a;暴力枚举&#xff08;超时&#xff09; 套用上述的容积公式&#xff0c;使用两个for循环来枚举出所有可能的情况&#xff0c;再挑出最大值即可&#xff0c;但是这种写法会超时&#xff0c;导致…...

java入门,程序=数据结构+算法

一、前言 在学习java的时候&#xff0c;我印象最深的一句话是&#xff1a;程序数据结构算法&#xff0c;对于写java程序来说&#xff0c;这就是java的入门。 二、java基本数据结构与算法 1、数据类型 java中的数据类型8种基本数据类型&#xff1a; 整型 byte 、short 、int…...

9.MySQL索引的操作

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 索引操作 查询索引 创建主键索引 唯一索引的创建 普通索引的创建 全文索引的创建 删除索引 索引创建原则 索引操作 查询索引 第一种方法&#xff1a; show keys from 表名\G 我们了解其中几个就好。 第二种方法…...

大型加油站3d全景虚拟现实展示平台实现全方位立体呈现

近年来&#xff0c;随着国民经济的快速发展&#xff0c;交通基础设施的不断改善&#xff0c;机动车保有量的持续飙升&#xff0c;以至于加油站的建设数量和密度也在不断扩张。加油站作为人流量大且常见的城市场景&#xff0c;对加油站进行安全防范措施具有非常重要的安全意义。…...

Reading:Deep dive into the OnPush change detection strategy in Angular

原文连接&#xff1a;IndepthApp 今天深入阅读并总结Angualr中onPush更新策略。 1. 两种策略 & whats Lview&#xff1f; Angular 实现了两种策略来控制各个组件级别的更改检测行为。这些策略定义为Default和OnPush&#xff1a; 被定义为枚举&#xff1a; export enum…...

野火霸天虎 STM32F407 学习笔记_1 stm32介绍;调试方法介绍

STM32入门——基于野火 F407 霸天虎课程学习 前言 博主开始探索嵌入式以来&#xff0c;其实很早就开始玩 stm32 了。但是学了一段时间之后总是感觉还是很没有头绪&#xff0c;不知道在学什么。前前后后分别尝试了江协科技、正点原子、野火霸天虎三次 stm32 的课程学习。江协科…...

@reduxjs/toolkit配置react-redux解决createStore或将在未来被淘汰警告

通常 我们用redux都需要通过 createStore 但目前 你去用它 基本都会被划线 甚至有点厉害的的编辑器 他会直接告诉你这个东西基本快被弃用了 这个应该大家都知道 最好不要用已经被明确未来或弃用的语法 因为一旦弃用这个系统就需要维护 而且说 一般会被淘汰的语法 本身也就是有…...

致敬1024天前的自己

今早打开手机就收到了来自CSDN的消息&#xff0c;哦&#xff0c;距离我发表第一篇技术博客已经过去1024个日夜了。 我第一次发技术博客是我大二做完我第一个网站时写的。因为网站需要上线服务器&#xff0c;涉及到不少linux相关的知识&#xff0c;我在自学的过程中走了不少弯路…...

〖Python网络爬虫实战㊱〗- JavaScript 网站加密和混淆

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000+python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者:爱吃饼干的小白鼠。Python领域优质创作者,2022年度…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...