Skip to content

表单

一、表单示例

vue
<template>
  <view class="content">
    <form @submit="onSubmit">
      <view class="form_box">
        <!-- 输入框 -->
        <van-field
          name="name"
          type="text"
          label="名称"
          placeholder="请输入名称"
          :value="formModel.name"
          :required="formRules.name.required"
          :error-message="objValidateErr.name"
          @input="onInput($event, 'name')"
        ></van-field>
        <van-field
          name="desc"
          type="text"
          label="描述"
          placeholder="请输入描述"
          :value="formModel.desc"
          :required="formRules.desc.required"
          :error-message="objValidateErr.desc"
          @input="onInput($event, 'desc')"
        ></van-field>
        <van-field
          name="phone"
          type="phone"
          label="手机号"
          placeholder="请输入手机号"
          :value="formModel.phone"
          :required="formRules.phone.required"
          :error-message="objValidateErr.phone"
          @input="onInput($event, 'phone')"
        ></van-field>
        <van-field
          name="password"
          type="phone"
          label="密码"
          placeholder="请输入密码"
          :password="!controlItem.showPassword"
          :value="formModel.password"
          :required="formRules.password.required"
          :error-message="objValidateErr.password"
          @input="onInput($event, 'password')"
        >
          <template #right-icon>
            <view
              @click.stop="controlItem.showPassword = !controlItem.showPassword"
            >
              <image
                v-if="controlItem.showPassword"
                class="showPawIcon"
                src="https://pro-core.babycdn.com/2022/09/zsh/xcx/images/home/show.png"
              ></image>
              <image
                v-else
                class="showPawIcon"
                src="https://pro-core.babycdn.com/2022/09/zsh/xcx/images/home/not_show.png"
              ></image>
            </view>
          </template>
        </van-field>
        <!-- 开关 -->
        <!-- 小程序样式问题,高度比size多2px -->
        <van-field name="open" label="是否开启">
          <template #input>
            <van-switch
              :checked="formModel.open"
              style="height:20px"
              size="18"
              @change="onInput($event, 'open')"
            />
          </template>
        </van-field>
        <!-- 单选框 -->
        <van-field
          name="sex"
          label="性别"
          :required="formRules.sex.required"
          :error-message="objValidateErr.sex"
        >
          <template #input>
            <van-radio-group
              :value="formModel.sex.toString()"
              direction="horizontal"
              @change="onInput($event, 'sex')"
            >
              <template v-for="(option, option_i) in formOption.sex">
                <van-radio :key="option_i" :name="option.key" shape="round">
                  {{ option.text }}
                </van-radio>
              </template>
            </van-radio-group>
          </template>
        </van-field>
        <!-- 复选框 -->
        <van-field
          name="likes"
          label="爱好"
          :required="formRules.likes.required"
          :error-message="objValidateErr.likes"
        >
          <template #input>
            <van-checkbox-group
              :value="formModel.likes"
              direction="horizontal"
              @change="onInput($event, 'likes')"
            >
              <template v-for="(option, option_i) in formOption.likes">
                <van-checkbox :key="option_i" :name="option.key" shape="square">
                  {{ option.text }}
                </van-checkbox>
              </template>
            </van-checkbox-group>
          </template>
        </van-field>
        <!-- 日期选择器 -->
        <view @click="controlItem.showDatePopup = true">
          <van-field
            name="date"
            label="日期"
            :value="formModel.date"
            readonly
            placeholder="请选择日期"
            :error-message="objValidateErr.date"
          >
          </van-field>
        </view>
        <van-popup
          :show="controlItem.showDatePopup"
          position="bottom"
          round
          @close="controlItem.showDatePopup = false"
        >
          <van-datetime-picker
            type="date"
            title="请选择日期"
            :value="new Date(formModel.date).getTime()"
            :min-date="formRules.date.minDate"
            :max-date="formRules.date.maxDate"
            @cancel="controlItem.showDatePopup = false"
            @confirm="onInputDate($event, 'date', 'showDatePopup')"
          />
        </van-popup>
        <!-- 评分 -->
        <van-field
          name="score"
          label="评分"
          :required="formRules.score.required"
          :error-message="objValidateErr.score"
        >
          <template #input>
            <van-rate
              :value="formModel.score"
              size="18"
              gutter="2"
              count="10"
              allow-half
              @change="onInput($event, 'score')"
            />
          </template>
        </van-field>
        <!-- 步进器-->
        <van-field
          name="num"
          label="数量"
          :required="formRules.num.required"
          :error-message="objValidateErr.num"
        >
          <template #input>
            <van-stepper
              :value="formModel.num"
              step="1"
              @change="onInput($event, 'num')"
            />
          </template>
        </van-field>
        <!-- 进度条 -->
        <van-field
          name="speed"
          label="进度"
          :required="formRules.speed.required"
          :error-message="objValidateErr.speed"
        >
          <template #input>
            <view class="slider_box">
              <van-slider
                :value="formModel.speed"
                step="1"
                :use-button-slot="true"
                @drag="onInputValue($event, 'speed')"
              >
                <view class="slider_btn" slot="button">
                  {{ formModel.speed }}
                </view>
              </van-slider>
            </view>
          </template>
        </van-field>
        <!-- 图片上传 -->
        <van-field
          name="image"
          label="图片base64上传"
          :required="formRules.image.required"
          :error-message="objValidateErr.image"
        >
          <template #input>
            <van-uploader
              :file-list="formModel.image"
              :max-count="4"
              accept="image"
              :imageFitL="'center'"
              @after-read="onInputImg($event, 'image')"
              @delete="onDelImg($event, 'image')"
            />
          </template>
        </van-field>
        <!-- oss图片上传 -->
        <van-field
          name="oss_img"
          label="图片oss上传"
          :border="false"
          :required="formRules.oss_img.required"
          :error-message="objValidateErr.oss_img"
        >
          <template #input>
            <van-uploader
              :file-list="formModel.oss_img"
              :max-count="4"
              accept="image"
              :imageFitL="'center'"
              @after-read="onInputImg($event, 'oss_img')"
              @delete="onDelImg($event, 'oss_img')"
            />
          </template>
        </van-field>
      </view>
      <view class="operation_box">
        <template v-for="(btn, btn_i) in operation">
          <template v-if="btn.type == 'submit'">
            <van-button
              :key="btn_i"
              size="normal"
              block
              round
              :type="btn.btnType"
              form-type="submit"
              :class="[btn.customClass]"
            >
              {{ btn.text }}
            </van-button>
          </template>
          <template v-else>
            <van-button
              :key="btn_i"
              size="normal"
              block
              round
              :type="btn.btnType"
              :class="[btn.customClass]"
            >
              {{ btn.text }}
            </van-button>
          </template>
        </template>
      </view>
    </form>
  </view>
</template>
<script>
import addData from "./add.js";

export default {
  components: {},
  data() {
    return {
      formModel: JSON.parse(JSON.stringify(addData.formModel)),
      formRules: addData.formRules,
      formOption: addData.formOption,
      validate: addData.validate,
      objValidateErr: addData.objValidateErr,
      controlItem: addData.controlItem,
      operation: addData.operation,
    };
  },
  onLoad() {},
  methods: {
    //input、switch、rate、field、radio、checkbox
    onInput(e, key) {
      console.log(e);
      let value = e.detail;
      this.formModel[key] = value;
      this.checkField(key);
    },
    //slider
    onInputValue(e, key) {
      console.log(e);
      let value = e.detail.value;
      this.formModel[key] = value;
      this.checkField(key);
    },
    //datetime-picker
    onInputDate(e, key, controlLey) {
      let date = new Date(e.detail);
      this.formModel[key] = `${date.getFullYear()}-${
        date.getMonth() + 1 >= 10
          ? date.getMonth() + 1
          : "0" + (date.getMonth() + 1)
      }-${date.getDate() >= 10 ? date.getDate() : "0" + date.getDate()}`;
      this.checkField(key);
      //关闭对应弹出框
      if (controlLey) {
        this.controlItem[controlLey] = false;
      }
    },
    //图片
    onInputImg(e, key) {
      this.formModel[key].push(e.detail.file);
    },
    onDelImg(e, key) {
      this.formModel[key].splice(e.detail.index, 1);
    },
    //验证单项
    checkField(key) {
      if (this.validate.checkField(key, this.formModel)) {
        delete this.objValidateErr[key];
      } else {
        this.objValidateErr[key] = this.validate.errorList[0].msg;
      }
    },
    onSubmit(e) {
      let submit = this.operation.filter((it) => it.type == "submit")[0];
      submit.fun(this);
    },
    touchFun(fun, item) {
      fun(item);
    },
  },
};
</script>

二、校验文件的使用

官方文档:https://github.com/wux-weapp/wx-extend/blob/master/docs/components/validate.md

  1. 引入文件
js
import WxValidate from "/src/libs/common/WxValidate.js";
  1. 使用
js
//表单对应的字段名
const formModel = {
  name: "",
  desc: "",
  phone: "",
  password: "",
  open: true,
  sex: "",
  likes: [],
  date: "",
  score: null,
  num: 1,
  speed: 0,
  image: [],
  oss_img: [],
  oss_file: [],
};

//表单对应字段的校验规则
const formRules = {
  name: { required: true, maxlength: 5 },
  desc: { required: true, maxlength: 50 },
  phone: { required: true, tel: true },
  password: { required: true, password: /^[0-9|a-z|A-Z]{6,16}$/ },
  open: { required: true },
  sex: { required: true },
  likes: { required: true, maxlength: 3 },
  date: {
    required: true,
    minDate: new Date().getTime(),
    maxDate: new Date("2023-12-12").getTime(),
  },
  score: { required: true },
  num: { required: true, max: 10 },
  speed: { required: true, min: 1 },
  image: { required: true },
  oss_img: { required: true },
};

//校验规则的错误提示
const validateMessage = {
  name: {
    required: "请输入名称",
    maxLength: "不能多于5个字符",
  },
  desc: {
    required: "请输入描述",
    maxLength: "不能多于50个字符",
  },
  phone: {
    required: "请输入手机号",
    tel: "请输入正确的手机号码",
  },
  password: {
    required: "请输入密码",
  },
  open: {},
  sex: {
    required: "请选择性别",
  },
  likes: {
    required: "请选择爱好",
    maxlength: "最多选择3个",
  },
  date: {
    required: "请选择日期",
  },
  score: {
    required: "请选择评分",
  },
  num: {
    required: "请选择数量",
    max: "数量不能大于10",
  },
  speed: {
    required: "请选择进度",
    max: "进度不能小于1",
  },
  image: { required: "请上传图片" },
  oss_img: { required: "请上传图片" },
};

const validate = new WxValidate(formRules, validateMessage);

// 自定义验证规则
validate.addMethod(
  "password",
  (value, param) => {
    return param.test(value);
  },
  "请输入6~16位由数字、大小字母组成的密码"
);

校验全部

js
validate.checkForm(formModel);

校验单项

js
validate.checkField(key, data);
  1. 内置的校验规则
序号规则描述
1required: true这是必填字段。
2email: true请输入有效的电子邮件地址。
3tel: true请输入 11 位的手机号码。
4url: true请输入有效的网址。
5date: true请输入有效的日期。
6dateISO: true请输入有效的日期(ISO),例如:2009-06-23,1998/01/22。
7number: true请输入有效的数字。
8digits: true只能输入数字。
9idcard: true请输入 18 位的有效身份证。
10equalTo: 'field'输入值必须和 field 相同。
11contains: 'ABC'输入值必须包含 ABC。
12minlength: 5最少要输入 5 个字符。
13maxlength: 10最多可以输入 10 个字符。
14rangelength: [5, 10]请输入长度在 5 到 10 之间的字符。
15min: 5请输入不小于 5 的数值。
16max: 10请输入不大于 10 的数值。
17range: [5, 10]请输入范围在 5 到 10 之间的数值。
  1. 方法
名称返回类型描述
checkForm(formModel)boolean验证所有字段的规则,返回验证是否通过。
checkField(key,data)boolean验证所有字段的规则,返回验证是否通过。
valid()boolean返回验证是否通过。
size()number返回错误信息的个数。
validationErrors()array返回所有错误信息。
addMethod(name, method, message)boolean添加自定义验证方法。

三、示例项目 SVN 地址

uni-app 项目:svn://39.107.13.238:12580/base_digi

示例


/_uniapp/src/pages/demo/add/wxapp/add.vue