微信小程序+vant 实现form表单 必填验证

4 阅读1分钟

 最近修改一个微信小程序+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);
    // 调用保存接口
  },
})