Vue中如何向子输入组件传递ref并正确获取输入值?
问题:通过ref获取子组件输入值时返回undefined
我尝试在表单提交时通过ref获取BaseInput子组件的输入值,但handleSubmit方法里console.log输出的email始终是undefined,相关代码如下:
父组件代码
<template> <form @submit.prevent="handleSubmit"> <div class="flex flex-col mt-10"> <form-label forInput="email" label="Email Address" /> <base-input type="email" name="email" ref="email" /> </div> </form> </template> <script> import BaseInput from "../UI/BaseInput.vue"; export default { components: { BaseInput, }, methods: { handleSubmit() { const email = this.$refs.email.value; console.log(email); }, }, }; </script>
子组件(BaseInput)代码
<template> <input :type="type" :name="name" :ref="name" /> </template> <script> export default { props: ["type", "name"], }; </script>
解决方案
问题根源
this.$refs.email获取到的是BaseInput子组件的实例,而非内部的<input>元素。子组件实例本身没有value属性,因此返回undefined。
方法1:在子组件中暴露输入值
修改子组件,通过计算属性实时暴露内部input的value:
<template> <input :type="type" :name="name" ref="inputRef" /> </template> <script> export default { props: ["type", "name"], computed: { value() { return this.$refs.inputRef.value; } } }; </script>
之后父组件可直接通过this.$refs.email.value获取输入值。
方法2:直接访问子组件内部的input元素
父组件修改handleSubmit方法,通过子组件实例的$refs获取内部input:
handleSubmit() { const email = this.$refs.email.$refs.email.value; console.log(email); }
⚠️ 不推荐:这种写法耦合性极高,子组件内部ref名称变更会直接导致父组件代码失效。
方法3:使用v-model(最优解)
遵循Vue单向数据流设计,给子组件添加v-model支持,这是最易维护的方案:
子组件修改:
<template> <input :type="type" :name="name" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template> <script> export default { props: ["type", "name", "modelValue"], emits: ["update:modelValue"] }; </script>
父组件修改:
<template> <form @submit.prevent="handleSubmit"> <div class="flex flex-col mt-10"> <form-label forInput="email" label="Email Address" /> <base-input type="email" name="email" v-model="email" /> </div> </form> </template> <script> import BaseInput from "../UI/BaseInput.vue"; export default { components: { BaseInput, }, data() { return { email: '' } }, methods: { handleSubmit() { console.log(this.email); }, }, }; </script>
内容的提问来源于stack exchange,提问作者Sebastien Stordeur
相关产品推荐
相关产品推荐

