这里讲一下使用elementUI时,封装v-model的组件遇到的问题。
这里就拿一个图片上传组件做例子:(这里是在el-upload上做二次封装)
<template>
<el-upload
class="img-uploader"
:action="uploadurl"
:headers="headers"
:show-upload-list="false"
:accept="accept"
:format="format"
:max-size="maxSize"
:before-upload="handleBeforeUpload"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:on-success="handleSuccess"
:on-error="handleError"
type="drag"
>
<div class="uploader">
<i class="icon icon-add">i>
div>
Upload>
template>
使用
最简单需求:
我们在上传图片后,需要自动触发表单的validate验证,上传后,要去掉已校验的错误提示。
在vue2.x时代,用的elementUI2.x,自己封装表单组件, 只需要在封装的组件 this.$emit('change', value)
触发一下或者利用el-upload自带的事件触发el-form-item的校验。
但在vue3.x后,vue本身就去掉了以前的$on,$off
功能,参见官方文档,而 推荐了一个事件管理库 mitt。
element-plus 也不使用eventHub在为表单创建事件。 也是用的mitt
。 参见form代码;
一般都直接用compositionAPI写法了,这里就简单抽取一个use方法:
import { inject } from 'vue';
/**
* 这段代码来自element-plus
* const elFormItem = reactive({
...toRefs(props),
size: sizeClass,
validateState,
removeValidateEvents,
addValidateEvents,
resetField,
clearValidate,
validate,
formItemMitt,
updateComputedLabelWidth,
})
*/
// useElFormItem.js
function useElFormItem() {
const elFormItem: any = inject('elFormItem');
// 触发element-plus 的 el-form-item的校验事件
const elFormEmit = value => {
if (elFormItem) {
elFormItem.formItemMitt.emit('el.form.blur', value);
elFormItem.formItemMitt.emit('el.form.change', value);
}
};
return { elFormItem, elFormEmit }
}
export default useElFormItem;
// ===================分割线===================
// 自定义组件中使用
import { useElFormItem } from '@/composables/useElFormItem.js';
// setup中使用
setup(){
// 处理在el-form-item中的校验事件
const { elFormEmit } = useElFormItem();
const handleSuccess = (res, file, fileList) => {
if (res.status === 'OK') {
const img = { url: res.data, name: file.name };
emit('update:modelValue', img);
// 触发表单验证
elFormEmit(img);
} else {
ElMessage.error(res.message);
}
return {
handleSuccess
}
}
其他代码就没贴了, 如果有需要,可以评论区评论,后续加上完整的图片上传组件(单图、多图、预览、下载等功能)