vue3封装表单组件,不能触发element-plus的form/form-item的验证事件,解决办法

前言: 在我们的项目开发中,经常需要封装一些自定义的表单组件来满足各种不同的表单提交需求, 并且通常会配合一些UI组件库写,提高开发效率。

这里讲一下使用elementUI时,封装v-model的组件遇到的问题。

这里就拿一个图片上传组件做例子:(这里是在el-upload上做二次封装)

  • ImageUpload.vue
<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代码;

vue3中触发表单事件写法

一般都直接用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
      }
}

其他代码就没贴了, 如果有需要,可以评论区评论,后续加上完整的图片上传组件(单图、多图、预览、下载等功能)

你可能感兴趣的:(js,vue.js,elementui,组件化)