Vuejs如何将@blur事件传递给自定义Input组件适配vee-validate
问题根因
Vue 3 中给自定义组件绑定的原生事件,默认会透传到组件的根DOM节点。你的自定义Input组件根节点是<div>,div本身默认不支持blur交互,所以父组件绑定的@blur事件根本不会触发,也不会传递到内部的原生input标签上。
另外补充:你在setup中打印props看不到blur相关内容是正常的,事件监听不会作为props传入组件,走的是Vue的独立事件机制。
方案1:显式转发blur事件
直接在自定义Input的内部原生input上监听blur事件,主动向外触发即可,修改src/components/Input.vue代码:
<template> <div class="mt-2"> <label :for="name" class="h5">Name</label> <input :type="type" :value="modelValue" @change="$emit('update:modelValue', $event.target.value)" <!-- 新增这行,转发blur事件 --> @blur="$emit('blur', $event)" :id="name" :placeholder="placeholder" /> </div> </template> <script> export default { name: 'Input', // 声明要触发的事件,属于可选规范,加了更符合Vue的类型校验要求 emits: ['update:modelValue', 'blur'], props: ["modelValue", 'name', 'type', 'placeholder'], setup(props) { console.log('props :>> ', props); } } </script>
改完后父组件的@blur="emailBlur"就可以正常触发,vee-validate的失焦校验也会正常运行。
方案2:全量透传属性和事件(更推荐)
如果你的自定义Input是通用组件,后续可能还要透传@focus、@input、disabled、autocomplete等大量原生属性和事件,可以用全量透传的方案,不用逐个手动转发:
修改src/components/Input.vue代码:
<template> <div class="mt-2"> <label :for="name" class="h5">Name</label> <!-- 新增v-bind="$attrs",把所有未被props接收的属性、事件都绑定到原生input上 --> <input :type="type" :value="modelValue" @change="$emit('update:modelValue', $event.target.value)" v-bind="$attrs" :id="name" :placeholder="placeholder" /> </div> </template> <script> export default { name: 'Input', // 关闭默认的根节点透传行为 inheritAttrs: false, emits: ['update:modelValue'], props: ["modelValue", 'name', 'type', 'placeholder'], setup(props) { console.log('props :>> ', props); } } </script>
这个方案下,父组件给Input组件绑定的任何原生属性、事件都会自动透传到内部的原生input上,不需要单独处理blur、focus等常见事件,后续扩展成本更低。
内容的提问来源于stack exchange,提问作者Wilker
相关产品推荐
相关产品推荐

