uni-app專案uview的表單驗證在小程式上不生效

!win !發表於2024-06-07

前情

uni-app是我比較喜歡的跨平臺框架,它能開發小程式/H5/APP(安卓/iOS),重要的是對前端開發友好,自帶的IDE讓開發體驗非常棒,公司專案就是主推uni-app,在uniapp生態中uView是其中非常好的全平臺的第三方開源ui庫,我在公司專案中果斷的使用了它。

坑位

在用uView做小程式表單驗證的時候,對於普通的驗證是沒有問題,如果要用到正則或者自定義驗證方法,發現在小程式不生效。

Why?

是自己大意了沒有閃,沒細看官方文擋,官方文擋在Form表單文擋最開頭就強調了,微信小程式要特殊處理,對於使用正則也是不行,有可能是用了正則就是走的自定義驗證方法了吧。

官方文擋

解決方案

在小程式中,使用uView的表單驗證如果你使用了正則驗證或者自定義驗證方法驗證,那就不能透過:rules給form元件傳驗證規則,只能透過setRules(rules)手動指定form的驗證規則才行。

不需要手動指定驗證規則:

<template>
	<view class="page-container">
		<u-form
			:model="form"
			:rules="rules"
			ref="addressForm"
		>
			<view class="form-wrap">
				<u-form-item
						label="姓名:"
						required
						labelWidth="auto"
						borderBottom
						prop="name"
				>
					<u--input
							v-model="form.name"
							inputAlign="right"
							placeholder="請輸入"
							border="none"
							type="number"
					></u--input>
				</u-form-item>
				<u-form-item
						label="手機號碼:"
						required
						labelWidth="auto"
						borderBottom
						prop="phone"
				>
					<u--input
							v-model="form.phone"
							inputAlign="right"
							placeholder="請輸入"
							border="none"
							type="number"
					></u--input>
				</u-form-item>
			</view>
		</u-form>
		<button @click="submit">提交</button>
	</view>
</template>

<script>
	
	export default {
		data() {
			return {
				form: {
					name: '',
					phone: '',
				},
				rules: {
					name: [
						{
							required: true,
							message: '請輸入聯絡人姓名',
							trigger: ['blur', 'change']
						}
					],
					phone: [
						{
							required: true,
							message: '請輸入手機號碼',
							trigger: ['blur', 'change']
						}
					]
				}
			}
		},
		methods: {
			submit() {
				this.$refs.addressForm.validate().then(res => {
					uni.$u.toast('校驗透過');
				}).catch(errors => {
					uni.$u.toast('校驗失敗');
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.form-wrap{
		padding:0 32rpx 40rpx 32rpx;
		::v-deep{
			.u-form-item__body__left__content__label{
				font-size: 32rpx!important;
				color: #111111;
			}
			.u-form-item__body{
				padding: 32rpx 0;
			}
			.input-placeholder{
				text-align: right;
			}
			.u-input__content__field-wrapper{
				margin-right: 4px;
			}
		}
	}
</style>

需要手動指定驗證規則,因為姓名使用了pattern/手機又使用了自定義的驗證方法:

<template>
	<view class="page-container">
		<u-form
			:model="form"
			ref="addressForm"
		>
			<view class="form-wrap">
				<u-form-item
						label="姓名:"
						required
						labelWidth="auto"
						borderBottom
						prop="name"
				>
					<u--input
							v-model="form.name"
							inputAlign="right"
							placeholder="請輸入"
							border="none"
							type="number"
					></u--input>
				</u-form-item>
				<u-form-item
						label="手機號碼:"
						required
						labelWidth="auto"
						borderBottom
						prop="phone"
				>
					<u--input
							v-model="form.phone"
							inputAlign="right"
							placeholder="請輸入"
							border="none"
							type="number"
					></u--input>
				</u-form-item>
			</view>
		</u-form>
		<button @click="submit">提交</button>
	</view>
</template>

<script>
	
	export default {
		data() {
			return {
				form: {
					name: '',
					phone: '',
				},
				rules: {
					name: [
						{
							required: true,
							message: '請輸入聯絡人姓名',
							trigger: ['blur', 'change']
						},
						// 正則判斷為字母或數字
						{
							pattern: /^[\u4e00-\u9fa5]+$/g,
							// 正則檢驗前先將值轉為字串
							transform(value) {
								return String(value);
							},
							message: '只能包含字母或數字'
						},
					],
					phone: [
						{
							required: true,
							message: '請輸入手機號碼',
							trigger: ['blur', 'change']
						}, {
							validator: (rule, value, callback) => {
								return uni.$u.test.mobile(value);
							},
							// pattern: /^1\d{10}$/,
							message: '請輸入正確的手機號',
							trigger: ['blur', 'change']
						}
					]
				}
			}
		},
		mounted() {
			// 手動提定rules
			this.$refs.addressForm.setRules(this.rules);
		},
		methods: {
			submit() {
				this.$refs.addressForm.validate().then(res => {
					uni.$u.toast('校驗透過');
				}).catch(errors => {
					uni.$u.toast('校驗失敗');
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.form-wrap{
		padding:0 32rpx 40rpx 32rpx;
		::v-deep{
			.u-form-item__body__left__content__label{
				font-size: 32rpx!important;
				color: #111111;
			}
			.u-form-item__body{
				padding: 32rpx 0;
			}
			.input-placeholder{
				text-align: right;
			}
			.u-input__content__field-wrapper{
				margin-right: 4px;
			}
		}
	}
</style>

相關文章