1
votes

In my parent Vue Page I'm calling a FormInput inside my form

new.vue

<b-form @submit.prevent="submit">
   <FormInput :name="name"/>
   <b-button @click="submit">Save</b-button>
<b-form>

<script>
 import FormInput from '~/components/Insiders/FormInput';
 export default {
   components: {
    FormInput
   },  
   data() {
     return {
      name: 'User A'
     }
   },
   methods:  {
     submit(event) {
      console.log(this.name)
     }
   }
 }
</script>

components/Insiders/FormInput.vue

<b-form-input v-model="name" type="text"></b-form-input>  
<script>
export default {
  props:   {
    name: { type: String, required: true }
  }
}
</script>

I'm getting an error: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "name"

What I'm expecting here is when I change the value in the input from new.vue I should be able to console.log the new value of name when I click the submit button.

How can I solve this?

1

1 Answers

1
votes

The right way for this use case is for you to support v-model for your component FormInput.

Essentially, you are building a component for user input. In that case, the component should take input prop and publish its value. Both can be done as a single configuration if you use v-model. ('Input' and 'Output' are configured with a single v-model attribute).

Refer to these articles:

https://alligator.io/vuejs/add-v-model-support/

https://scotch.io/tutorials/add-v-model-support-to-custom-vuejs-component

Edit:

v-model approach makes the FormInput component easy to use. So, the change in New.vue is simple:

<b-form @submit.prevent="submit">
   <FormInput :v-model="name"/>
   <b-button @click="submit">Save</b-button>
<b-form>

<script>
 import FormInput from '~/components/Insiders/FormInput';
 export default {
   components: {
    FormInput
   },  
   data() {
     return {
      name: 'User A'
     }
   },
   methods:  {
     submit(event) {
      console.log(this.name)
     }
   }
 }
</script>

But, the FormInput component has to still do some extra work, in order not to mutate the actual input.

<b-form-input :value="value" @input='updateVal' type="text"></b-form-input>  
<script>
export default {
  props:   {
    value: { type: String, required: true }
  },
  methods: {
      updateVal: function(val){
           this.$emit('input', val);
      }
  }
}
</script>