uniapp中结合vue2的表单验证做法
在uniapp中vue2.0开发微信小程序时的表单验证,假设一个页面表单提交中,人员类型有:教师和学生,他们对应的填写字段不同,我们需要怎么处理验证和提交字段,实现过程如下:
<template>
<!-- 模板部分与之前一致 -->
<view class="container">
<u-form
ref="form"
:model="formData"
:rules="rules"
:label-width="120"
>
<!-- 来访人员类型 -->
<u-form-item
label="来访人员类型"
prop="type"
required
>
<u-radio-group
v-model="formData.type"
@change="handleTypeChange"
placement="row"
>
<u-radio
:label="item.label"
:value="item.value"
v-for="(item, index) in typeOptions"
:key="index"
></u-radio>
</u-radio-group>
</u-form-item>
<!-- 共同字段:姓名 -->
<u-form-item
label="姓名"
prop="name"
required
>
<u-input
v-model="formData.name"
placeholder="请输入姓名"
></u-input>
</u-form-item>
<!-- 共同字段:身份证 -->
<u-form-item
label="身份证号"
prop="idCard"
required
>
<u-input
v-model="formData.idCard"
placeholder="请输入18位身份证号"
></u-input>
</u-form-item>
<!-- 老师专属字段 -->
<template v-if="formData.type === 'teacher'">
<u-form-item
label="教师编号"
prop="teacherNo"
required
>
<u-input
v-model="formData.teacherNo"
placeholder="请输入11位教师编号"
></u-input>
</u-form-item>
<u-form-item
label="职位"
prop="position"
required
>
<u-input
v-model="formData.position"
placeholder="请输入职位"
></u-input>
</u-form-item>
</template>
<!-- 学生专属字段 -->
<template v-if="formData.type === 'student'">
<u-form-item
label="学号"
prop="studentNo"
required
>
<u-input
v-model="formData.studentNo"
placeholder="请输入9位学号"
></u-input>
</u-form-item>
<u-form-item
label="年级"
prop="grade"
required
>
<u-input
v-model="formData.grade"
placeholder="请输入年级"
></u-input>
</u-form-item>
<u-form-item
label="班级"
prop="class"
required
>
<u-input
v-model="formData.class"
placeholder="请输入班级"
></u-input>
</u-form-item>
</template>
<u-button
type="primary"
@click="submitForm"
style="margin-top: 20px;"
>
提交
</u-button>
</u-form>
</view>
</template>
<script>
export default {
data() {
return {
formData: {
type: 'teacher',
name: '',
idCard: '',
// 老师字段
teacherNo: '',
position: '',
// 学生字段
studentNo: '',
grade: '',
class: ''
},
typeOptions: [
{ label: '老师', value: 'teacher' },
{ label: '学生', value: 'student' }
],
// 字段映射表:明确各类型必须提交的字段
fieldMap: {
teacher: ['type', 'name', 'idCard', 'teacherNo', 'position'],
student: ['type', 'name', 'idCard', 'studentNo', 'grade', 'class']
},
rules: {
// 验证规则与之前一致
type: [
{ required: true, errorMessage: '请选择来访人员类型' }
],
name: [
{ required: true, errorMessage: '请输入姓名'},
{ min: 2, max: 10, errorMessage: '姓名长度在2-10个字符之间' }
],
idCard: [
{ required: true, errorMessage: '请输入身份证号'},
{
pattern: /^\d{17}[\dXx]$/,
errorMessage: '请输入有效的18位身份证号',
trigger: 'blur'
}
],
teacherNo: [
{ required: true, errorMessage: '请输入教师编号'},
{
pattern: /^\d{11}$/,
errorMessage: '教师编号必须是11位数字',
trigger: 'blur'
}
],
position: [
{ required: true, errorMessage: '请输入职位' }
],
studentNo: [
{ required: true, errorMessage: '请输入学号'},
{
pattern: /^\d{9}$/,
errorMessage: '学号必须是9位数字',
trigger: 'blur'
}
],
grade: [
{ required: true, errorMessage: '请输入年级' }
],
class: [
{ required: true, errorMessage: '请输入班级' }
]
}
}
},
methods: {
handleTypeChange() {
if (this.formData.type === 'teacher') {
this.formData.studentNo = ''
this.formData.grade = ''
this.formData.class = ''
} else if (this.formData.type === 'student') {
this.formData.teacherNo = ''
this.formData.position = ''
}
this.$refs.form.resetValidation()
},
submitForm() {
this.$refs.form.validate().then(valid => {
if (valid) {
this.onSubmit()
}
}).catch(err => {
console.log('验证失败:', err)
})
},
onSubmit() {
const currentType = this.formData.type
const requiredFields = this.fieldMap[currentType]
// 优化点:先筛选字段,再拷贝,避免包含多余字段
const submitData = requiredFields.reduce((data, field) => {
// 对每个字段单独拷贝(处理可能的引用类型,虽然这里都是基本类型)
data[field] = typeof this.formData[field] === 'object'
? JSON.parse(JSON.stringify(this.formData[field]))
: this.formData[field] // 基本类型直接赋值
return data
}, {})
// 提交逻辑
const apiUrl = currentType === 'teacher' ? '/api/getTeacher' : '/api/getStudent'
uni.showLoading({ title: '提交中...' })
uni.request({
url: apiUrl,
method: 'POST',
data: submitData, // 仅包含当前类型所需字段
success: (res) => {
uni.hideLoading()
if (res.data.code === 0) {
uni.showToast({ title: '提交成功', icon: 'success' })
console.log('提交数据(精确字段):', submitData)
} else {
uni.showToast({ title: res.data.msg || '提交失败', icon: 'none' })
}
},
fail: () => {
uni.hideLoading()
uni.showToast({ title: '网络请求失败', icon: 'none' })
}
})
}
}
}
</script>