最近修改一个微信小程序+vant组件的项目,需要增加一个表单页面并添加必填验证,原本是按照vant官方文档中的写法放上去,结果发现不行,微信小程序有自己的一套写法,以下是输入框、单选、日期选择器表单写法,其他的表单也是类似。
wxml文件:
<van-form id="ruleForm" bind:submit="onSubmit">
<van-field value="{{ruleForm.studentName}}" label="姓名" placeholder="姓名" bind:change="onFieldChange" data-field="studentName" required :rules="[{ required: true, message: '请填写姓名' }]" error-message="{{error.studentName}}" />
<van-field value="{{ruleForm.birthDay}}" label="出生日期" placeholder="请选择出生日期" required readonly bind:tap="openDatePicker" rules="{{[{ required: true, message: '请选择出生日期' }]}}" error-message="{{error.birthDay}}" />
<van-popup show="showDatePicker" show="{{showDatePicker}}" position="bottom" round bind:close="hideDatePicker">
<van-datetime-picker type="date" value="{{currentDate}}" min-date="{{minDate}}" max-date="{{maxDate}}" bind:confirm="onDateConfirm" bind:cancel="hideDatePicker" />
</van-popup>
<van-field name="sex" label="性别" required rules="{{[{ required: true, message: '请选择性别' }]}}" error-message="{{error.sex}}">
<van-radio-group slot="input" value="{{ruleForm.sex}}" bindchange="onFieldChange" data-field="sex" direction="horizontal">
<van-radio name="M">男</van-radio>
<van-radio name="F">女</van-radio>
</van-radio-group>
</van-field>
<van-field value="{{ruleForm.lxdh}}" type="tel" label="手机号" placeholder="手机号" bind:change="onFieldChange" data-field="lxdh" required :rules="[{ required: true, message: '请填写手机号' }]" readonly error-message="{{error.lxdh}}" />
<div style="margin: 16px;">
<van-button round block type="info" native-type="submit" bind:click="onSubmit">提交</van-button>
</div>
</van-form>
js文件
Page({
data: {
ruleForm: {
studentName: '',
birthDay:'',
sex: '',
lxdh: '',
},
rules: {
studentName: [{ required: true, message: '请填写用户名' }],
birthDay: [{ required: true, message: '请选择出生日期' }],
sex: [{ required: true, message: '请选择性别' }],
lxdh: [{ required: true, message: '请填写手机号' }],
},
error: {
studentName: '',
birthDay: '',
sex: '',
lxdh: '',
},
showDatePicker: false, // 控制日期选择器显示
minDate: new Date(1900, 0, 1).getTime(), // 最小日期(1900-01-01)
maxDate: new Date().getTime(), // 最大日期(今天)
currentDate: new Date().getTime(), // 当前选中日期
},
// 显示日期选择器
openDatePicker() {
this.setData({
showDatePicker: true,
currentDate: this.data.ruleForm.birthDay
? new Date(this.data.ruleForm.birthDay).getTime()
: new Date().getTime()
});
},
// 隐藏日期选择器
hideDatePicker() {
this.setData({ showDatePicker: false });
},
// 确认选择日期
onDateConfirm(e) {
const date = new Date(e.detail);
const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
console.log(formattedDate);
this.setData({
'ruleForm.birthDay': formattedDate,
showDatePicker: false
},
() => {
console.log(this.data.ruleForm.birthDay);
});
},
// 表单验证
validateForm(validatorKeys) {
console.log('validatorKeys', validatorKeys);
const keys = validatorKeys || Object.keys(this.data.ruleForm)
keys.forEach(key => {
const rule = this.data.rules[key]
if (rule) {
const value = this.data.ruleForm[key]
for (let i = 0; i < rule.length; i++) {
const ruleItem = rule[i]
if (ruleItem.required) {
this.setData({
[`error.${key}`]: value.length > 0 ? '' : ruleItem.message
})
if (!value) {
break
}
} else if (ruleItem.validator) {
const flag = ruleItem.validator(value)
this.setData({
[`error.${key}`]: flag ? '' : ruleItem.message
})
if (!flag) {
break
}
}
}
}
})
},
// 统一处理字段变更
onFieldChange(e) {
const field = e.currentTarget.dataset.field; // 直接获取字段名
const value = e.detail; // 直接获取输入值
console.log(`ruleForm.${field}`);
this.setData({
[`ruleForm.${field}`]: value // 更新数据
});
const rule = this.data.rules[field]
console.log(rule);
if (rule) {
this.validateForm([field])
}
},
// 表单提交
onSubmit(e) {
console.log('表单提交', this.data.ruleForm);
// 调用保存接口
},
})