由于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. ansible 配置详解

    ansible 安装方式 ansible安装常用两种方式,yum安装和pip程序安装.下面我们来详细介绍一下这两种安装方式. 使用 pip(python的包管理模块)安装 首先,我们需要安装一个pyt ...

  2. nexus AD 集成配置

    nexus AD 集成配置 管理用户登录 点击设置图标-->LDAP-->Create connection 进入AD 集成配置页面 Connection配置 User and group ...

  3. python之struct详解

    python之struct详解 2018-05-23 18:20:29 醉小义 阅读数 20115更多 分类专栏: python   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...

  4. Linux:Linux安装配置JDK1.8

    1  在/usr/local   文件夹下新建一个文件夹software ,将JDK放到此文件夹中 并在此文件夹下解压执行命令  tar  zxvf  jdk-8u144-linux-x64.tar. ...

  5. Maven | 把jar包安装到本地仓库

    使用的场景 自己写的工具类想安装到本地 从Maven仓库中下载不下来的jar 使用的步骤 首先要保证自己的Maven配置全局环境变量,如果没有配置过maven全局变量,可以按照下面的步骤配置一下: 先 ...

  6. Git submodule 拉取子模块

    $ git clone https://code.Xcode.com.client.git Cloning into 'vipkid-pc-client'... Username for 'https ...

  7. Git的安装和配置 -入门

    Git的版本有很多种,适应各种windows,IOS, Linux平台的安装. 我用的是linux Centos7的版本: 1. 安装命令用Yum, 非常简单就可以安装完毕. yum install ...

  8. WIN10 GMSSL编译

    从git上拉取GMSSL代码 从http://gmssl.org/上可以拉取,或者直接从git上https://github.com/guanzhi/GmSSL拉也行. 我是在git上下的,文件为gm ...

  9. python mysql类

    import pymysql class MysqlHelper(object): conn = None def __init__(self, host, username, password, d ...

  10. java课堂动手动脑及课后实验总结

      动手动脑一:枚举   输出结果: false false true SMALL MEDIUM LARGE 分析和总结用法 枚举类型的使用是借助ENUM这样一个类,这个类是JAVA枚举类型的公共基本 ...