Appearance
表单
一、表单示例
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
- 引入文件
js
import WxValidate from "/src/libs/common/WxValidate.js";
- 使用
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 | required: true | 这是必填字段。 |
2 | email: true | 请输入有效的电子邮件地址。 |
3 | tel: true | 请输入 11 位的手机号码。 |
4 | url: true | 请输入有效的网址。 |
5 | date: true | 请输入有效的日期。 |
6 | dateISO: true | 请输入有效的日期(ISO),例如:2009-06-23,1998/01/22。 |
7 | number: true | 请输入有效的数字。 |
8 | digits: true | 只能输入数字。 |
9 | idcard: true | 请输入 18 位的有效身份证。 |
10 | equalTo: 'field' | 输入值必须和 field 相同。 |
11 | contains: 'ABC' | 输入值必须包含 ABC。 |
12 | minlength: 5 | 最少要输入 5 个字符。 |
13 | maxlength: 10 | 最多可以输入 10 个字符。 |
14 | rangelength: [5, 10] | 请输入长度在 5 到 10 之间的字符。 |
15 | min: 5 | 请输入不小于 5 的数值。 |
16 | max: 10 | 请输入不大于 10 的数值。 |
17 | range: [5, 10] | 请输入范围在 5 到 10 之间的数值。 |
- 方法
名称 | 返回类型 | 描述 |
---|---|---|
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