vue 动态添加 多项目 表单_antd vue中,如何给表单动态添加input,解决遇到一些坑...

本文介绍在Ant Design Vue中动态添加和删除多项目表单时遇到的验证和数据清除问题,以及解决方案。重点是表单验证的友好性,删除表单项后仍存在的数据提交问题,通过`form.getFieldDecorator`注册字段,使用`clearField`方法来清理数据,确保表单状态正确。同时,文章提供了一段关键代码示例来说明如何处理动态表单的添加、删除和验证。
摘要由CSDN通过智能技术生成

最近做项目用的组件库Ant Design Vue,这个组件看起来文档很详细,但也会遇到一些意想不到的问题,最后看文档没办法解决,只能去看源码,折腾了好久,终于把问题给解决了,遇到的问题主要是当添加input的时候验证不能友好的使用,当一个input添加,然后删除,提交表单的时候会提示填写删除的input,还有个问题就是当把填写好的内容,删除提交的时候,已删除的内容还是能提交到后台,用方法处理

form.getFieldValue('email').splice(index, 1)

form.getFieldValue('truename').splice(index, 1)

form.setFieldsValue({

keys: keys.filter(key => key !== index),

email: form.getFieldValue('email'),

truename: form.getFieldValue('truename')

})

这样设置的值的时候,数据还是没删除成功,还能提交到后台,后来才知道需要先注册

注册,这样setFieldsValue方法才能成功,但是添加了之后也没删除成功,

this.form.getFieldDecorator('keys', { initialValue: [0], preserve: true })

this.form.getFieldDecorator('email', { initialValue: [], preserve: false })

this.form.getFieldDecorator('truename', { initialValue: [], preserve: false })

经过看代码后来发现文档里面有个没提示到this.form.clearField(''),用这个方法总算解决了这个问题。

但是上面方法也有个不好的方法就是,keys在删除的时候不能按顺序排列,造成values数组里面也出现了空字段现象,需要重新处理数组,把字段设置成preserve: false。用对象数组循环数据,用循环的中的索引值组成keys,这样在删除,添加的时候,keys的索引跟values数组一直对应,values数组中不会出现空元素现象,在表单提交的时候加上需要验证的字段,这样问题就解决了,大致的代码如下

通过邮件邀请,无需审核

发送邀请给指定的邮箱,对方只需进行个人账户设置即可直接加入团队

ref="inviteForm"

layout="inline"

:form="form"

class="demo-form-inline"

@submit.prevent="submitHandle('inviteForm')"

>

v-for="(item,index) in formData"

:key="index"

class="invite-item"

>

:required="false"

>

v-decorator="[

`email[${index}]`,

{

validateTrigger: [ 'blur'],

rules: [{

required: true,

whitespace: true,

message: '请输入邮箱'

},

{

validator: isEmailRe

},

{

validator:isErrorEmail

},

{

type:'email',

message: '邮箱格式不正确'

}

]

}

]"

placeholder="请输入邮箱"

/>

v-if="item.isreg *1 === 1"

class="member-name"

>

已注册用户

class="member-name"

>

v-decorator="[

`truename[${index}]`,{

rules:[{ required: true, message: '请输入姓名'}]

}]"

placeholder="姓名"

/>

v-if="form.getFieldValue('keys').length > 1&&(index!==0)"

class="del-invite-btn"

@click="delteFormItem(index)"

>

删除

class="add-invite-btn"

@click="addItem"

>

新增

type="primary"

html-type="submit"

:disabled="loading"

>

发送邀请

import SecondCrumb from '@/components/pc/organization/invite/SecondCrumb'

import { mapActions } from 'vuex'

export default {

components: {

SecondCrumb

},

data () {

return {

initTeamId: '',

isLoading: false,

submitting: false,

initItem: {},

formData: [

{

email: '',

truename: '',

isreg: 0

}

]

}

},

computed: {

loading () {

return this.submitting

},

args () {

return this.$route.query

},

keys () {

let arr = []

this.formData.forEach((val, index) => {

arr.push(index)

})

return arr

}

},

watch: {

},

created () {

this.form = this.$form.createForm(this)

this.form.getFieldDecorator('keys', { initialValue: [], preserve: true })

this.form.getFieldDecorator('email', { initialValue: [], preserve: false })

this.form.getFieldDecorator('truename', { initialValue: [], preserve: false })

},

mounted () {

},

methods: {

...mapActions('organization/invite', ['ajaxSave', 'ajaxEmail']),

addItem () {

this.formData.push(

{

email: '',

truename: '',

isreg: 0

}

)

const { form } = this

form.setFieldsValue({

keys: this.keys

})

},

// 删除邀请成员表单行

delteFormItem (index) {

const { form } = this

// can use data-binding to set

this.formData.splice(index, 1)

form.getFieldValue('email').splice(index, 1)

form.getFieldValue('truename').splice(index, 1)

form.setFieldsValue({

keys: this.keys,

email: form.getFieldValue('email'),

truename: form.getFieldValue('truename')

})

},

setFormData (data) {

const { formData } = this

for (let i = 0; i < data.length; i++) {

formData[i].truename = data[i]

}

},

submitHandle () {

this.form.validateFieldsAndScroll(['keys', 'email', 'truename'], async (err, values) => {

const { form, formData } = this

if (!err) {

this.setFormData(form.getFieldValue('truename'))

const chain = await this.ajaxSave()

chain.params({ cid: this.args.cid * 1, inviteinfo: formData })

.setForm(this.form)

.fetch()

}

})

},

isEmailRe (rule, value, callback) {

const length = this.form.getFieldValue('email').filter(item => item === value).length

if (length > 1) {

callback(new Error('邮箱重复!'))

} else {

callback()

}

},

async isErrorEmail (rule, value, callback) {

const index = this.form.getFieldValue('email').indexOf(value)

const item = this.formData[index]

let chain = await this.ajaxEmail()

await chain.params({ email: value, cid: this.args.cid })

.onNetSuccess((raw) => {

const res = raw.data

if (!res.error) {

if (res.payload.isreg === 1) {

// this.isHasReg = true

item.isreg = 1

item.truename = ''

} else {

item.isreg = 0

}

item.email = value

} else {

// item.msg = res.message

// item.isreg = 3

if (value && res.message) {

callback(new Error(res.message))

} else {

callback()

}

}

})

.fetch()

}

}

}

Antd 2.x 在 Vue 表单验证和 React 类似,可以通过 `Form` 组件的 `validateFields` 方法来触发校验,校验未通过时,可以通过 `getFieldError` 方法获取错误信息,并将焦点设置到出错的表单控件上。以下是示例代码: ``` <template> <a-form :form="form" @submit="handleSubmit"> <a-form-item label="Username" :colon="false" :validateStatus="getFieldError('username') ? 'error' : ''" :help="getFieldError('username')"> <a-input v-decorator="['username', { rules: [{ required: true, message: 'Please input your username!' }] }]" /> </a-form-item> <a-form-item label="Password" :colon="false" :validateStatus="getFieldError('password') ? 'error' : ''" :help="getFieldError('password')"> <a-input-password v-decorator="['password', { rules: [{ required: true, message: 'Please input your password!' }] }]" /> </a-form-item> <a-form-item> <a-button type="primary" @click="handleClick">Submit</a-button> </a-form-item> </a-form> </template> <script> import { FormModel, Input, Button, Alert } from 'ant-design-vue'; import { defineComponent } from 'vue'; export default defineComponent({ components: { 'a-form': FormModel, 'a-form-item': FormModel.Item, 'a-input': Input, 'a-input-password': Input.Password, 'a-button': Button, 'a-alert': Alert, }, data() { return { form: null, }; }, mounted() { this.form = this.$form.createForm(this); }, methods: { handleClick() { this.form.validateFields().catch(() => { const errorFields = this.form.getFieldsError(); const firstErrorField = errorFields.find((item) => item.errors.length); if (firstErrorField) { const control = this.form.getFieldInstance(firstErrorField.name); control.focus(); } }); }, handleSubmit(e) { e.preventDefault(); this.form.validateFields((err, values) => { if (!err) { console.log('Received values of form: ', values); } }); }, getFieldError(name) { const fieldError = this.form.getFieldError(name); if (fieldError) { return fieldError[0]; } return ''; }, }, }); </script> ``` 在模板,我们使用 `getFieldError` 方法获取每个表单控件的错误信息,并根据错误信息设置相应的 `validateStatus` 和 `help` 属性。 在方法,我们首先使用 `this.$form.createForm(this)` 创建一个表单实例。然后,我们在 `handleClick` 方法使用 `form.validateFields()` 方法触发表单校验。如果校验未通过,这个方法会返回一个 Promise,我们可以通过 `.catch()` 方法捕获校验错误。 在错误处理,我们首先使用 `form.getFieldsError()` 方法获取所有的表单控件的错误信息。然后,我们使用 `Array.find()` 方法找到第一个存在错误信息的表单控件,然后使用 `form.getFieldInstance()` 方法获取这个表单控件的实例。最后,我们使用 `control.focus()` 方法将焦点设置到这个表单控件上,从而达到跳转到未检验通过的地方的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值