项目中需要动态生成一个表单,并校验。我先做了一个动态表单的Demo:
<template>
<view class="form-example">
<uni-forms ref="form" :modelValue="formData" :rules="rules" label-width="80px">
<view class="group">
<uni-forms-item label="小组名称" name="groupName" required>
<uni-easyinput type="text" v-model="formData.groupName" placeholder="请输入小组名称" />
</uni-forms-item>
<button type="primary" size="mini" @click="addMember">新增组员</button>
<view class="group-item" v-for="(member,mIndex) in formData.memberList" :key="member.id">
<view class="group-item-title">
<text>成员{{mIndex+1}}</text>
<text class="del" v-if="formData.memberList.length > 1" @click="delMember(member.id)">删除</text>
</view>
<uni-forms-item
label="姓名"
required
:name="['memberList', mIndex,'name']"
:rules="[{'required': true,errorMessage: '请输入姓名'}]"
>
<uni-easyinput type="text" v-model="formData.memberList[mIndex].name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item
label="年龄"
required
:name="['memberList', mIndex,'age']"
:rules="[{'required': true,errorMessage: '请输入年龄'}]"
>
<uni-easyinput v-model="formData.memberList[mIndex].age" placeholder="请输入年龄" />
</uni-forms-item>
<uni-forms-item
label="性别"
required
:name="['memberList', mIndex,'sex']"
:rules="[{'required': true,errorMessage: '请选择性别'}]"
>
<uni-data-checkbox v-model="formData.memberList[mIndex].sex" :localdata="sexs" />
</uni-forms-item>
<button type="primary" size="mini" @click="addContact(mIndex)">+新增联系人</button>
<view class="contact-list">
<view class="contact-list-item" v-for="(contact, cIndex) in member.contactList" :key="contact.id">
<view class="contact-list-title">
<text>联系人{{cIndex+1}}</text>
<text class="del" v-if="member.contactList.length > 1" @click="delContact(member.id,contact.id)">删除联系人</text>
</view>
<uni-forms-item
label="联系人"
required
:name="['memberList', mIndex,'contactList',cIndex,'name']"
:rules="[{'required': true,errorMessage: '请输入联系人'}]"
>
<uni-easyinput type="text" v-model="formData.memberList[mIndex].contactList[cIndex].name" placeholder="请输入联系人" />
</uni-forms-item>
<uni-forms-item
label="电话"
:name="['memberList', mIndex,'contactList',cIndex,'phone']"
:rules="[{'required': true,errorMessage: '请输入电话'}]"
required>
<uni-easyinput type="text" v-model="formData.memberList[mIndex].contactList[cIndex].phone" placeholder="请输入联系电话" />
</uni-forms-item>
</view>
</view>
</view>
</view>
</uni-forms>
<button type="primary" @click="submitForm">新增小组</button>
</view>
</template>
<script>
export default {
data() {
return {
formData:{
id: this.getRandomId(),
groupName:'',
memberList:[]
},
rules: {
groupName:{
rules: [{
required: true,
errorMessage: '小组名称不能为空'
}]
},
},
sexs: [{
text: '男',
value: 0
}, {
text: '女',
value: 1
}]
}
},
onLoad(){
this.addMember()
},
methods: {
//获取一个随机id
getRandomId(){
const randomNum = Math.floor(Math.random() * 100000); // 生成一个随机数
const timestamp = Date.now(); // 获取当前时间戳
return `${timestamp}${randomNum}`;
},
//新增成员
addMember() {
this.formData.memberList.push({
id: this.getRandomId(),
name: '',
age: '',
sex:0,
contactList:[{
id: this.getRandomId(),
name:'',
phone:''
}]
});
},
//新增联系人
addContact(mIndex){
this.formData.memberList[mIndex].contactList.push({
id: this.getRandomId(),
name:'',
phone:''
});
},
//删除成员
delMember(id) {
let ind = this.formData.memberList.findIndex(v => v.id === id)
this.formData.memberList.splice(ind, 1)
},
//删除联系人
delContact(id,childId) {
const newArr = this.formData.memberList.map(item => {
if(item.id === id){
let ind = item.contactList.findIndex(v => v.id === childId)
item.contactList.splice(ind, 1)
}
return item
})
this.formData.memberList = newArr
},
//新增小组
submitForm() {
this.$refs['form'].validate().then(res => {
const parmas = {...this.formData}
console.log("提交表单",parmas)
}).catch(err => {
console.log('err', err);
})
},
}
}
</script>
<style lang="scss" scoped>
.form-example{
padding:20rpx;
.group-item{
border:2rpx #6395f6 solid;
padding:20rpx;
border-radius: 8rpx;
margin-bottom:20rpx;
.group-item-title{
display:flex;
justify-content: space-between;
height:50rpx;
.del{
color:#f24141;
font-size:24rpx;
}
}
}
.contact-list-item{
padding-top:40rpx;
&:not(:first-child){
border-top:2rpx #6395f6 dashed;
}
.contact-list-title{
display:flex;
justify-content: space-between;
height:50rpx;
.del{
color:#f24141;
font-size:24rpx;
}
}
}
}
</style>