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>

使用

<el-form :rules: { imgUrl: [{ required: true, message: '请上传用户头像' }]}>
	<el-form-item>
 	 	<CustomUpload v-model="baseForm.imgUrl" @change="handleChange">
	</el-form-item>
</el-form>

最简单需求:

我们在上传图片后,需要自动触发表单的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
      }
}

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值