表单与上传组件校验

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

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

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

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

背景

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

相关推荐
伊织code2 小时前
Cap‘n Web - JavaScript原生RPC系统
前端·javascript·rpc
周尛先森2 小时前
匠心管控 package.json:让前端依赖告别臃肿与混乱
前端
90后的晨仔2 小时前
Vue3 事件处理详解:从入门到精通
前端·vue.js
西洼工作室2 小时前
设计模式与原则精要
前端·javascript·设计模式·vue
IT_陈寒2 小时前
SpringBoot 性能优化的 7 个冷门技巧,让你的应用快如闪电!
前端·人工智能·后端
清风细雨_林木木3 小时前
flutter 里面的渐变色设置
前端·flutter
yourkin6663 小时前
初识react
前端·javascript·react.js
゜ eVer ㄨ3 小时前
React第四天——hooks
前端·react.js·前端框架
Jyywww1213 小时前
uniapp中pinia(setup语法)使用流程
开发语言·javascript·uni-app