Vue自定义输入组件emit('input')返回两个值导致v-model绑定失效
问题根因
- 核心问题1:你在组件内部新声明的
valueref和父组件传入的props.value完全无关联,既没有用props.value作为初始值,也没有监听props.value的变化更新内部ref,两者完全独立运行,自然无法同步。 - 核心问题2:版本适配问题,如果你使用的是Vue3,默认的v-model绑定协议和Vue2不同:Vue2默认绑定prop为
value、监听input事件;Vue3默认绑定prop为modelValue、监听update:modelValue事件,协议不匹配会导致v-model无法接收事件回调。 - 额外问题:原生input的@input事件默认会传递事件对象作为参数,你未显式处理的情况下可能会导致emit携带多余参数,就是你看到的返回两个值的情况。
解决方案
适配Vue2项目
修改组件代码如下:
<template> <div class="input-field"> <input type="text" v-model="inputValue" :id="inputId" placeholder="" /> <label :for="inputId">{{ label }}</label> </div> </template> <script> import { computed } from "@vue/reactivity"; export default { name: "InputField", props: { value: { type: String, default: "" }, inputId: { type: String }, label: { type: String }, }, setup(props, { emit }) { // 用计算属性做桥接,自动同步props和emit事件 const inputValue = computed({ get() { return props.value }, set(newVal) { emit("input", newVal) } }) return { inputValue }; }, }; </script> <style lang="less" scoped> </style>
适配Vue3项目
使用Vue3默认的v-model协议修改:
<template> <div class="input-field"> <input type="text" v-model="inputValue" :id="inputId" placeholder="" /> <label :for="inputId">{{ label }}</label> </div> </template> <script> import { computed } from "vue"; export default { name: "InputField", props: { modelValue: { type: String, default: "" }, inputId: { type: String }, label: { type: String }, }, setup(props, { emit }) { const inputValue = computed({ get() { return props.modelValue }, set(newVal) { emit("update:modelValue", newVal) } }) return { inputValue }; }, }; </script> <style lang="less" scoped> </style>
修改后父组件代码不需要做任何调整,v-model即可正常同步,也不会再出现多余的事件返回参数。
内容的提问来源于stack exchange,提问作者Anupam Krishna
相关产品推荐
相关产品推荐

