表单与上传组件校验

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

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

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

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

背景

公司有一个较老的项目,使用的是 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 在表单校验和上传校验上的问题。

相关推荐
freeWayWalker3 分钟前
Vue通用缩放容器
前端·javascript·vue.js
Hello--_--World11 分钟前
VUE:逻辑复用
前端·javascript·vue.js
陶甜也27 分钟前
3D智慧城市:blender建模、骨骼、动画、VUE、threeJs引入渲染,飞行视角,涟漪、人物行走
前端·3d·vue·blender·threejs·模型
患得患失94933 分钟前
【前端websocket】企业级功能清单
前端·websocket·网络协议
落魄江湖行33 分钟前
基础篇四 Nuxt4 全局样式与 CSS 模块
前端·css·typescript·nuxt4
禅思院34 分钟前
前端性能优化:从"术"到"道"的完整修炼指南
前端·架构·前端框架
叫我一声阿雷吧38 分钟前
JS 入门通关手册(43):async/await 原理与异常处理(实战 + 面试,彻底搞懂)
javascript·异常处理·promise·前端面试·async/await·generator·异步编程
架构师老Y2 小时前
003、Python Web框架深度对比:Django vs Flask vs FastAPI
前端·python·django
小陈工5 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
xiaotao1319 小时前
第九章:Vite API 参考手册
前端·vite·前端打包