自定义组件触发 element-plus el-form-item 组件的 validate

1,706 阅读1分钟

背景

在开发时封装了富文本组件,但在富文本组件触发 change 事件后,不会触发 el-form-item 的校验,搜了下相关的帖子,发现不生效,所以记录一下这次解决的过程。

实现

找到的一个解决方法,来自这篇文章的Element Plus 表单触发自定义组件校验规则:trigger](juejin.cn/post/704148…)

<script lang="ts">
import { useTrigger } from '@/utils/validatorRules'
export default defineComponent({
  emits: ['update:modelValue'],
  setup (props, { emit }) {
    const { emitTrigger } = useTrigger()
    const change = (key: string, e?: any) => {
      emit('update:modelValue', e)
      emitTrigger(e)
    }
    return {
      change,
    }
  }
})
</script>

因为是 21 年底的,个人推断是 element-plus 版本更新了,写法有所变化,所以我查看了 element-plus 的源码:

image.png

现在 el-form-item 是通过 provide 的方式,提供给子组件一些暴露的方法,比如 validate,这时候就可以在我们的自定义组件里,通过 inject 来获取到父级 el-form-item 提供的方法。

封装一个 useTrigger.js:

import { formItemContextKey } from 'element-plus';
import { inject } from 'vue';

export function useTrigger() {
  const elFormItem = inject(formItemContextKey);
  const emitTrigger = (trigger = 'change') => {
    if (elFormItem?.validate) {
      elFormItem.validate(trigger);
    }
  };
  return { emitTrigger };
}

使用

封装一个组件,伪代码:

<script setup>
const { emitTrigger } = useTrigger()

const handleInput = () => {
 // ...
 emitTrigger('input')
}
const handleBlur = () => {
 // ...
 emitTrigger('blur')
}

</script>

自定义组件需要被 el-form-item 包裹才能有效:

<template>
  <el-form :model="form" :rules="rules">
    <el-form-item prop='x'>
      <custom-component v-model="form.x />
    </el-form-item>
  </el-form>
</template>

gist 地址,欢迎 star