Vue3动态创建组件时如何给循环渲染的input组件传递事件
Vue3 动态配置自定义input组件的事件传递方案
要实现基于JSON配置动态创建input组件同时传递事件,核心是把事件规则整合到配置中,配合Vue的动态绑定能力实现,根据业务场景可以选择两种实现方案:
方案1:独立事件回调(适合不同输入组件逻辑差异大的场景)
直接在JSON配置的每个输入项中定义events字段,存储事件名和对应的处理函数:
// 动态生成input的配置 const inputConfig = [ { type: 'text', label: '用户名', field: 'username', // 自定义属性可以放props字段 props: { placeholder: '请输入用户名', maxLength: 20 }, // 要绑定的事件集合 events: { input: (val) => { console.log('用户名输入变更:', val) }, blur: () => { // 执行用户名唯一性校验逻辑 } } }, { type: 'number', label: '年龄', field: 'age', events: { change: (val) => { if(val < 0) alert('年龄不能为负数') } } } ]
在模板循环渲染时,用v-on直接绑定整个事件对象即可,Vue会自动解析绑定所有事件:
<template> <div class="form-wrap"> <div v-for="item in inputConfig" :key="item.field"> <label>{{ item.label }}</label> <CustomInput v-model="formData[item.field]" <!-- 动态绑定自定义属性 --> v-bind="item.props" <!-- 动态绑定所有配置的事件 --> v-on="item.events" /> </div> </div> </template>
方案2:统一事件处理(适合事件逻辑可复用的场景)
如果所有输入组件的事件逻辑可以抽象为统一处理,配置里只需要声明要监听的事件名即可,触发时带上当前输入项的唯一标识(比如绑定的字段名)区分:
const inputConfig = [ { type: 'text', label: '用户名', field: 'username', events: ['input', 'blur'] }, { type: 'number', label: '年龄', field: 'age', events: ['change'] } ]
模板中绑定事件时透传字段信息:
<template> <div class="form-wrap"> <div v-for="item in inputConfig" :key="item.field"> <label>{{ item.label }}</label> <CustomInput v-model="formData[item.field]" @input="val => handleCommonEvent(item.field, 'input', val)" @blur="val => handleCommonEvent(item.field, 'blur', val)" @change="val => handleCommonEvent(item.field, 'change', val)" /> </div> </div> </template> <script setup> import { reactive } from 'vue' const formData = reactive({}) const handleCommonEvent = (field, eventName, value) => { // 统一处理逻辑,按field和eventName区分执行对应操作 console.log(`字段${field}触发${eventName}事件,当前值:${value}`) } </script>
注意事项
- 自定义Input组件内部要正确抛出对应事件,比如原生input触发输入时,要执行
emit('input', e.target.value),外层才能正常接收事件 - 如果事件处理函数定义在setup中,要确保绑定的时候可以正常访问到,不要出现未定义的问题
内容的提问来源于stack exchange,提问作者johan
相关产品推荐
相关产品推荐

