uniapp 中使用uview表单验证时,自定义扩展的表单,在改变时无法触发表单验证处理;

uniapp中使用uview表单时,自定义扩展的表单,无法及时触发uview表单验证,但是在提交的时候,表单又可以进行表单验证。其中的原因是uview触发机制所决定的。处理方法:需要在自定义扩展表单组件内部加入一个触发方法,触发on-form-change或者on-form-blur事件,这两个在rules里面对应 trigger:change 或 blur;(注意触发机制需要放在微任务或宏任务中,避免验证触发混乱),下面以on-form-change该事件为例子:

第一步: 在自定义扩展组件内部加入以下代码:(此代码在表单改变的时候触发,val为改变的结果值,后面会以自定义日期组件为例子,贴上完整代码)

javascript 复制代码
onChangeFormItemValid(val) {
			this.$nextTick(() => {
				this.dispatch('u-form-item', 'on-form-change', val);
			});
		},

2、完成之上步骤,应该可以看到dispatch方法报错,那是因为我们的代码中没有这个方法。这个方法需要用到uview表单中的公共方法,使用如下:在自定义扩展表单组件中引入 Emitter,并使用

mixins: Emitter: 如图:

最后附上代码,供参考:

javascript 复制代码
<template>
	<view class="mn-calendar">
		<view class="select-input" @click="!disabled && (show = true)">
			<template v-if="$slots.default || $scopedSlots.default">
				<slot :title="getTitle"></slot>
			</template>
			<template v-else>
				{{ getTitle || '请选择' }}
				<template v-if="!disabled">
					<view class="clear-icon" @click.stop="onClear" v-show="getTitle"><u-icon name="close"
							size="28"></u-icon>
					</view>
					<view class="arrow-icon"><u-icon name="arrow-right" size="38" color="#999"></u-icon></view>
				</template>
			</template>
		</view>
		<u-calendar v-model="show" :mode="mode" @change="onChange" :max-date="maxDate"></u-calendar>
	</view>
</template>

<script>
import moment from 'js/moment.js'
import Emitter from '@/uview-ui/libs/util/emitter.js';
export default {
	name: "mn-calendar",
	mixins: [Emitter],
	props: {
		value: String | Array,
		mode: {
			type: String,
			default: 'date'
		},
		disabled: {
			type: Boolean,
			default: false
		},
		maxDate: {
			type: String,
			default: moment().add(1, 'year').format('YYYY-MM-DD')
		}
	},
	data() {
		return {
			text: '',
			show: false
		};
	},
	computed: {
		getTitle() {
			if (!this.value) return ''
			if (this.mode === 'range') {
				return this.value.length == 2 ? `${this.value[0]} ~ ${this.value[1]}` : ''
			} else {
				return this.value
			}
		},
	},
	methods: {
		onChange(e) {
			if (this.mode === 'range') {
				const { startDate, endDate } = e
				this.$emit('input', [startDate, endDate])
			} else {
				this.$emit('input', e.result)
			}
			this.onEmitChange()
		},
		onEmitChange() {
			this.$emit('change', this.value)
			this.$nextTick(() => {
				this.dispatch('u-form-item', 'on-form-change', this.value);
			});
		},
		onClear() {
			if (this.mode === 'range') {
				this.$emit('input', [])
			} else {
				this.$emit('input', '')
			}
			this.onEmitChange()
		}
	}
}
</script>

<style lang="scss" scoped>
.mn-calendar {
	width: 100%;
}

.select-input {
	width: 100%;
	box-sizing: border-box;
	padding-right: 78rpx;
	padding-left: 0;
	position: relative;

	.clear-icon {
		position: absolute;
		right: 38rpx;
		padding: 20rpx;
		top: 50%;
		transform: translateY(-50%);
	}

	.arrow-icon {
		position: absolute;
		right: 0;
		top: 50%;
		transform: translateY(-50%);
	}
}
</style>

就可以按照u-input一样进行使用了,为了扩展性更强。

相关推荐
默子昂1 分钟前
ollama 自定义ui
开发语言·python·ui
#麻辣小龙虾#17 分钟前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar22 分钟前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github
weixin_4713830335 分钟前
Taro-02-页面路由
前端·taro
星栈独行42 分钟前
Makepad 应用如何读文件、调接口、保存数据
前端·程序人生·ui·rust·github
赴生-1 小时前
C++进阶 C++11(下)
开发语言·c++
一 乐1 小时前
家政服务管理系统|基于springboot + vue家政服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·家政服务管理系统
IT_陈寒1 小时前
Vite热更新失效?可能你在用Windows
前端·人工智能·后端
烬羽2 小时前
后端返回的 JSON 字符串,浏览器怎么"看懂"的?——Ajax 全链路拆解
javascript
tedcloud1232 小时前
taste-skill部署教程:打造个性化AI推荐工作流
服务器·前端·人工智能·系统架构·edge