Vue.js字段更新异常:输入标题时链接字段同步更新问题
It sounds like two main issues are at play here: your updateValue method is firing twice (causing duplicate events), and your fields are syncing values because they’re either sharing a data property or the event handling isn’t properly scoped to each field. Let’s break down the fix step by step.
Step 1: Fix the Double Emission in the Child Component
First, let’s address why updateValue runs twice. This usually happens if your form-input component uses both v-model AND a manual @input handler that calls updateValue—this creates duplicate input events.
Replace your child component’s code with a clean, standard implementation that emits the event only once:
<!-- form-input.vue --> <template> <div class="form-group"> <label :for="name">{{ labelvalue }}</label> <input :type="type" :name="name" :value="value" :placeholder="placeholder" :class="classname" :id="id" @input="$emit('input', $event.target.value)" /> </div> </template> <script> export default { props: ['label', 'labelvalue', 'type', 'placeholder', 'name', 'value', 'classname', 'id'] } </script>
This removes any redundant updateValue method and directly emits the input event once whenever the input changes.
Step 2: Bind Each Field to Its Own Data Property
In your parent App.vue, make sure you have separate data properties for title and link, then use v-model to bind each field to its respective property (this is cleaner than separate handlers):
<!-- App.vue --> <template> <div> <form-input v-model="title" :label="'title'" :labelvalue="'Titel'" :type="'text'" :placeholder="''" :name="'title'" :classname="'form-control'" :id="''" ></form-input> <form-input v-model="link" :label="'Link'" :labelvalue="'Link'" :type="'text'" :placeholder="''" :name="'link'" :classname="'form-control'" :id="''" ></form-input> </div> </template> <script> import FormInput from './components/form-input.vue'; export default { components: { FormInput }, data() { return { title: '', link: '' } } } </script>
If You Prefer Separate Handlers
If you want to keep using handleTitle and handleLink instead of v-model, adjust the parent like this:
<!-- App.vue --> <template> <div> <form-input @input="handleTitle" :value="title" :label="'title'" :labelvalue="'Titel'" :type="'text'" :placeholder="''" :name="'title'" :classname="'form-control'" :id="''" ></form-input> <form-input @input="handleLink" :value="link" :label="'Link'" :labelvalue="'Link'" :type="'text'" :placeholder="''" :name="'link'" :classname="'form-control'" :id="''" ></form-input> </div> </template> <script> import FormInput from './components/form-input.vue'; export default { components: { FormInput }, data() { return { title: '', link: '' } }, methods: { handleTitle(newValue) { this.title = newValue; }, handleLink(newValue) { this.link = newValue; } } } </script>
Why This Works
- No Double Emissions: The child component now emits the
inputevent exactly once per user input, eliminating the duplicateupdateValuecalls. - Independent Binding: Each field is linked to its own unique data property (
titleandlink), so typing in one won’t affect the other.
Content of the question originates from Stack Exchange, asked by Bas

