表单与上传组件校验

大家好,我是 前端架构师 - 大卫

更多优质内容请关注微信公众号 @程序员大卫

初心为助前端人🚀,进阶路上共星辰✨,

您的点赞与关注❤️,是我笔耕不辍的灯💡。

背景

公司有一个较老的项目,使用的是 Vue2 搭配 Element UI(1.4.13)。 在这个版本中,Form 表单的校验方法不会返回 Promise,因此需要自己封装。 另外,上传组件(Upload)不像 Input、Select 那样能直接触发校验,因此也需要单独处理。

1. 封装表单校验 Promise

为了解决 Form 表单校验不返回 Promise 的问题,可以封装一个 validateForm 方法,使其返回 Promise,便于在 async/await 语法下使用。

html 复制代码
<!-- 示例表单 -->
<template>
	<el-form ref="form" :model="form" :rules="rules" label-width="80px">
		<el-form-item label="用户名" prop="username">
			<el-input v-model="form.username"></el-input>
		</el-form-item>
		<el-form-item label="密码" prop="pass">
			<el-input
				type="password"
				v-model="form.pass"
				auto-complete="off"
			></el-input>
		</el-form-item>
		<el-form-item>
			<el-button type="primary" @click="submitForm">提交</el-button>
		</el-form-item>
	</el-form>
</template>

<script>
import validateForm from "./utils/validateForm";

export default {
	data() {
		return {
			form: { username: "", pass: "" },
			rules: {
				username: [
					{ required: true, message: "请输入用户名", trigger: "blur" },
				],
				pass: [{ required: true, message: "请输入密码", trigger: "blur" }],
			},
		};
	},
	methods: {
		async submitForm() {
			try {
				await validateForm(this.$refs.form);
				console.log("验证通过");
			} catch (_e) {
				console.log(_e); // ['请输入用户名', '请输入密码']
			}
		},
	},
};
</script>
js 复制代码
// 封装的 Promise 校验方法
export function validateForm(form) {
	return new Promise((resolve, reject) => {
		const getErrorMsg = () =>
			form.fields
				.filter((item) => item.validateMessage)
				.map((item) => item.validateMessage);
  
		form.validate((valid) => {
			if (valid) {
				resolve();
			} else {
				reject(getErrorMsg());
			}
		});
	});
}

2. 附件上传的校验

对于上传组件,直接调用 validateField 方法即可。 不过需要注意以下几点:

  1. 字段名 upload 要一致

data.form.uploaddata.rules.upload 以及 el-form-itemprop="upload" 必须保持一致。

  1. 校验类型必须是数组

rules.upload.type 必须写成 "array",因为上传的文件列表是一个数组。

  1. 事件监听要完整

只监听 onChange 不够,因为它不会捕捉附件移除事件。必须同时监听 onSuccessonRemove,在文件列表变化时手动触发校验。

html 复制代码
<template>
	<el-form ref="form" :model="form" :rules="rules" label-width="80px">
		<el-form-item label="附件上传" prop="upload">
			<el-upload
				action="https://jsonplaceholder.typicode.com/posts/"
				:on-success="onSuccess"
				:on-remove="onRemove"
				:file-list="form.fileList"
			>
				<el-button size="small" type="primary">点击上传</el-button>
				<div slot="tip" class="el-upload__tip">
					只能上传jpg/png文件,且不超过500kb
				</div>
			</el-upload>
		</el-form-item>
	</el-form>
</template>

<script>
export default {
	data() {
		return {
			form: { upload: [] },
			rules: {
				upload: [
					{
						type: "array",  // 注意这里的类型是 array
						required: true,
						message: "请输入附件",
						trigger: "change",
					},
				],
			},
		};
	},
	mounted() {
		this.$refs.form.validate((valid) => {
			console.log("valid", valid);
		});
	},
	methods: {
		updateFileList(fileList) {
			this.form.upload = fileList;
			this.$refs.form.validateField("upload");
		},
		onRemove(_file, fileList) {
			this.updateFileList(fileList);
		},
		onSuccess(_response, _file, fileList) {
			this.updateFileList(fileList);
		},
	},
};
</script>

总结

Element UI(1.4.13) 中:

  • 表单校验需要自己封装 Promise 方法,方便在 async/await 里使用。
  • 上传组件要注意字段名、校验类型一致,并在文件上传或删除时手动调用 validateField

这样就能比较优雅地解决老版本 Element UI 在表单校验和上传校验上的问题。

相关推荐
支撑前端荣耀7 分钟前
从零实现前端监控告警系统:SMTP + Node.js + 个人邮箱 完整免费方案
前端·javascript·面试
重铸码农荣光11 分钟前
🎯 从零搭建一个 React Todo 应用:父子通信、状态管理与本地持久化全解析!
前端·react.js·架构
用户40993225021211 分钟前
Vue3 v-if与v-show:销毁还是隐藏,如何抉择?
前端·vue.js·后端
Mr_chiu12 分钟前
🚀 效率暴增!Vue.js开发必知的15个神级提效工具
前端
JimmyWhat12 分钟前
Vue单页应用路由404问题:服务器配置与Hash模式解决方案
vue.js
shanLion12 分钟前
Vite项目中process报红问题的深层原因与解决方案
前端·javascript
烟袅14 分钟前
从零构建一个待办事项应用:一次关于组件化与状态管理的深度思考
前端·javascript·react.js
前端小万17 分钟前
草稿
前端
闲云一鹤19 分钟前
将地图上的 poi 点位导出为 excel,并转换为 shp 文件
前端·cesium
JIngJaneIL20 分钟前
基于springboot + vue健康管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端