由于vue3用的人还不多,所以有些问题博主踩了坑只能自己爬出来了,特此做个记录。如有错误,请大家指正。

  回归正题,我所做的业务是,动态添加表单项,对每一项单独做校验,效果如下:

  

  主要代码如下:

 1 <a-form
2 name="custom-validation"
3 ref="formRef"
4 :model="modelRef"
5 :rules="rules"
6 v-bind="layout"
7 @finish="handleFinish"
8 @finishFailed="handleFinishFailed"
9 >
10 <div class="card-box">
11 <div class="card-head">基础信息</div>
12 <div class="card-body">
13 <a-form-item label="食材名称" name="name">
14 <a-input v-model:value="modelRef.name" autocomplete="off" />
15 </a-form-item>
16 <a-form-item label="食材编号" name="foodNumber">
17 <a-input v-model:value="modelRef.foodNumber" autocomplete="off" />
18 </a-form-item>
19 <a-form-item label="食材类型" name="foodType">
20 <a-select v-model:value="modelRef.foodType" placeholder="">
21 <a-select-option value="shanghai">Zone one</a-select-option>
22 <a-select-option value="beijing">Zone two</a-select-option>
23 </a-select>
24 </a-form-item>
25 <a-form-item label="食材产地" name="birthplace">
26 <a-input v-model:value="modelRef.birthplace" autocomplete="off" />
27 </a-form-item>
28 </div>
29 </div>
30 <div class="card-box">
31 <div class="card-head">营养成分信息</div>
32 <div class="card-body">
33 <a-button primary shape="round" @click="onAdd">
34 <PlusSquareOutlined /> 新增
35 </a-button>
36 <div class="nutrients-content-box">
37 <a-row type="flex" justify="space-between" align="middle">
38 <a-col :span="5" v-for="(item,index) in modelRef.nutrients" :key="index">
39 <div class="nutrients-input-box card-box">
40 <div>{{item.name}}</div>
41 <div class="flex-align-end">
42 <div>
             注:form.item的name必须与modelRef里面的字段保持一致,否则无法实现自动校验,所以此处name使用动态数据,
          当数组nutrients值改变时,就往modelRef里面加字段(与这里的name保持一致)。下面代码有说明
43 <a-form-item :name="item.id+'nutrients'"

                     当name设置成功了,此处的规则便会在change触发后执行
44 :rules="[{validator: validateNutrients, trigger: 'change'}]">
45 <a-input v-model:value="item.value" @change="onFieldChange(item)"/>
46 </a-form-item>
47 </div>
48 <span>{{item.unit}}</span>
49 </div>
50 </div>
51 </a-col>
52 </a-row>
53 </div>
54 </div>
55 </div>
56 <div class="op-btn-box">
57 <a-form-item :wrapper-col="{ span: 12, offset: 18 }">
58 <a-button>取消</a-button>
59 <a-button type="primary" style="margin-left: 10px" html-type="submit">保存</a-button>
60 </a-form-item>
61 </div>
62 </a-form>
 1 import { onMounted, reactive, toRefs, watch } from 'vue'
2 setup() {
    //表单校验里的name值必须与此处的字段保持一致
3 const modelRef = reactive({
4 name: '',
5 foodNumber: '',
6 foodType: null,
7 birthplace: '',
8 nutrients: [],
9 })
10 const layout = {
11 labelCol: { span: 2 },
12 wrapperCol: { span: 6 },
13 }
    //此处为动态表单的自定义规则
14 const validateNutrients = async (rule, value) => {
15 if (!value) {
16 return Promise.reject(new Error('请输入数值'))
17 }
18 const numReg = /^(?!0+(?:\.0+)?$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$/
19 if (!numReg.exec(value)) {
20 return Promise.reject(new Error('请输入正确数字'))
21 }
22 }
23
    //其他普通的校验,可做统一处理
24 const rules = {
25 name: [
26 { required: true, message: '请输入食材名称', trigger: 'change' },
27 { max: 20, message: '最多输入20字', trigger: 'change' },
28 ],
29 foodNumber: [
30 { required: true, message: '请输入食材编号', trigger: 'change' },
31 { max: 20, message: '最多输入20字', trigger: 'change' },
32 ],
33 foodType: [
34 { required: true, message: '请选择食材类型', trigger: 'change' },
35 ],
36 birthplace: [
37 { required: true, message: '请输入食材产地', trigger: 'change' },
38 { max: 20, message: '最多输入20字', trigger: 'change' },
39 ],
40 }
41
    //此处是关键,modelRef.nutrients是遍历动态表单所用的数组,当数组值改变时,往modelRef里面加字段,与上面的动态循环出来的form.item的name保持一致
42 watch(
43 () => modelRef.nutrients,
44 val => {
45 if (val.length) {
46 val.forEach(item => {
47 modelRef[`${item.id}nutrients`] = item.value
48 })
49 }
50 },
51 )
52 /* 提交保存 */
53 const handleFinish = (values) => {
54 console.log(values)
55 }
56 const handleFinishFailed = (errors) => {
57 console.log(errors)
58 }
   //输入框的值改变时,需要更新modelRef里动态添加的字段的值,否则校验会出错。
59 const onFieldChange = (item) => {
60 modelRef[`${item.id}nutrients`] = item.value
61 }
62
63 return {
64 ...toRefs(state),
65 modelRef,
66 rules,
67 layout,
68 handleFinish,
69 handleFinishFailed,
70 validateNutrients,
71 onFieldChange,
72 }
73 },

 

antd+vue3实现动态表单的自动校验的更多相关文章

  1. form-create 3.0 版本发布,好用的Vue3版本动态表单生成组件

    form-create 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成组件.支持2个UI框架,并且支持生成任何 Vue 组件.内置20种常用表单组件和自定义组件,再复杂 ...

  2. react antd form多组表单数据处理

    import React from 'react'; import {Form, InputNumber, Input, DatePicker, Button, Select, Icon} from ...

  3. 【react】实现动态表单中嵌套动态表单

    要实现一个功能动态表单中嵌套动态表单如下: 仔细看看antd的文档其实不难 具体步骤如下 1.建立一个 名为 ConcatRegion的组件(动态表单A)代码如下 export function Co ...

  4. [K/3Cloud] 如何从被调用的动态表单界面返回数据

    在需要返回数据的地方调用表单返回方法完成数据返回 this.View.ReturnToParentWindow(retData); 在调用界面的回调函数中取出返回结果的ReturnData即可使用. ...

  5. Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)

    Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成) 动态表单生成 ElementUI官网引导 Element表单生成 Element动态增减表单,在线代码 关键配置 templa ...

  6. 简易OA漫谈之工作流设计(六,快捷表单和动态表单)

    如果没有表单设计功能,我们一般建物理表,再把表单挂接到流程, 我们可以把外接表单的地址填到表单地址中,地址中会传递一个id. 如果使用外接表单,在审批的时候可能会“不太友好”,因为在审批单上看不到任何 ...

  7. angularjs 动态表单, 原生事件中调用angular方法

    1. 原生事件中调用angular方法, 比如 input的onChange事件想调用angular里面定义的方法 - onChange="angular.element(this).sco ...

  8. vue 开发系列(八) 动态表单开发

    概要 动态表单指的是我们的表单不是通过vue 组件一个个编写的,我们的表单是根据后端生成的vue模板,在前端通过vue构建出来的.主要的思路是,在后端生成vue的模板,前端通过ajax的方式加载后端的 ...

  9. Struts动态表单(DynamicForm)

    动态表单的含义是不要手动定义,直接在配置文件中进行定义. 1.手动进行定义 <form-beans > <form-bean name="userForm" ty ...

随机推荐

  1. Linux指令手册 (一)

    指令格式 指令主体 [选项] [操作对象] 一个完整的指令是由"指令主体"."选项"和"操作对象"组成的,其中指令主体只能有一个,选项有零个 ...

  2. 《汇编语言程序设计》(Professional Assembly Language)学习笔记(二)

    挖坑:学习笔记(一)讲述如何在 Windows Vmware 上安装 Ubuntu 20.04 实践环境 本文是基于Ubuntu 20.04平台进行实验,下文中的解决方法都基于此前提 问题记录 问题一 ...

  3. (转发)forward与(重定向)redirect的区别

    (转发)forward与(重定向)redirect的区别 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服 ...

  4. leetcode 861 翻转矩阵后的得分

    1. 题目描述 2.思路分析: 1. 首先这里的翻转分为了行翻转和列翻转,我们这里只需要求如何翻转后得到最大值,有点贪心的思想,因为最大值一定是固定的 至于是什么路径到达的最大值不是我们所关心的,我们 ...

  5. 最常见的安全漏洞– Acunetix Web应用程序漏洞报告2021

    每年,Acunetix都会为您提供最常见的Web安全漏洞和网络外围漏洞的分析.我们的年度Web应用程序漏洞报告(现已成为Invicti AppSec指标的一部分)是基于从Acunetix在线获得的真实 ...

  6. 深入理解Java并发类——AQS

    目录 什么是AQS 为什么需要AQS AQS的核心思想 AQS的内部数据和方法 如何利用AQS实现同步结构 ReentrantLock对AQS的利用 尝试获取锁 获取锁失败,排队竞争 参考 什么是AQ ...

  7. 「AGC034E」 Complete Compress

    「AGC034E」 Complete Compress 显然可以枚举根. 然后把某两棵棋子同时往深度浅的方向提,即对不存在祖先关系的两个棋子进行操作. 如果能到达那么就更新答案. 问题转化为如何判定能 ...

  8. mysql中函数cast使用

    CAST函数语法规则是:Cast(字段名 as 转换的类型 ),其中类型可以为: CHAR[(N)] 字符型DATE 日期型DATETIME 日期和时间型DECIMAL float型SIGNED in ...

  9. WIN10小技巧

    WIN10激活: powershell管理员运行slmgr /skms kms.03k.orgslmgr /ato CMD:%TEMP% 全选垃圾,删除 手机投屏到WIN10:win+i---系统-- ...

  10. Requests方法 -- session方法

    import requests#禁用安全请求警告from requests.packages.urllib3.exceptions import InsecureRequestWarningreque ...