0
votes

I am trying to learn some vuejs and am struggling to understand how to pass data from a parent component to its child component. I know more is required but i'm not sure which way to go. How do pass the name in an input field in the parent component when the submit button is pressed to display in the child component?

I have tried using v-model because from what i have read and understand it is supposed to do what i need but it updates it without me even needing to press the button.

//Parent component
<template>
  <div id="app">
    <form @submit.prevent="handleSubmit">
        <input type="text" name="fname" id="fname" placeholder="First Name" v-model="fname">
        <input type="text" name="lname" id="lname" placeholder="Last Name" v-model="lname">
        <input type="submit" value="Submit Name">
    </form>
    <Name lname="lname" fname="fname"></Name>
  </div>
</template>
<script>
    import Name from './components/fullName.vue'
    export default {
        name: 'app',
        data () {
            return {
                fname: '',
                lname: '',
                submittedFname: '',
                submittedLname: ''
            }
        },
        components: {
            Name
        },
        methods: {
            handleSubmit() {
                submittedFname = fname,
                submittedLname = lname
            }
        }
    }
</script>
//child component
<template>
    <div id="my-name">
        <label>Your name is:</label>
        {{ submittedFname }} {{ submittedLname }}
    </div>
</template>
<script>
    export default {
        name: 'my-name',
        data () {
            return {
            }
        },
        props: {
            submittedFname: String,
            submittedLname: String
        }
    }
</script>

I am expecting to display the full name on the child component when the button is pressed but instead it is displayed as i am typing it.

2

2 Answers

1
votes
//Parent component
<template>
  <div id="app">
    <form>
        <input type="text" name="fname" id="fname" placeholder="First Name" v-model="fname">
        <input type="text" name="lname" id="lname" placeholder="Last Name" v-model="lname">
    </form>
    <button @click="handleSubmit(fname,lname)">submit</button>
    <Name :submittedFname="submittedFname" :submittedLname="submittedLname" ></Name>
  </div>
</template>
<script>
    import Name from './components/fullName.vue'
    export default {
        name: 'app',
        data () {
            return {
                fname: '',
                lname: '',
                submittedFname: '',
                submittedLname: ''
            }
        },
        components: {
            Name
        },
        methods: {
            handleSubmit(fname,lname) {
                this.submittedFname = fname,
                this.submittedLname = lname
            }
        }
    }
</script>

//child component
<template>
    <div id="my-name">
        <label>Your name is:</label>
        {{ submittedFname }} {{ submittedLname }}
    </div>
</template>
<script>
    export default {
        name: 'my-name',
        data () {
            return {
            }
        },
        props: {
            submittedFname: String,
            submittedLname: String
        }
    }
</script>

in case I forgot some things here are screenshots: Parent component enter image description here

child component

enter image description here

0
votes

v-model means that the fname and lname instance data properties are updated each time the value of their respective input elements changes (it uses the input event behind the scenes). You then pass fname and lname directly as props to the child component. These props are reactive so it behaves as you see and the name is updated as you type.

To only change the name when submit is pressed, you can do this:

  • Add 2 more data properties in the parent component (e.g. submittedfname and submittedlname)
  • Add an @submit event listener on the form that copies the values from fname and lname to submittedfname and submittedlname
  • Use submittedfname and submittedlname as props for the child component.

Working code:

//Parent component
Vue.component('app', {
  template: `
  <div>
    <form @submit.prevent="handleSubmit">
        <input type="text" name="fname" id="fname" placeholder="First Name" v-model="fname">
        <input type="text" name="lname" id="lname" placeholder="Last Name" v-model="lname">
        <input type="submit" value="Submit Name">
    </form>
    <name-comp :submittedFname="submittedFname" :submittedLname="submittedLname"></Name>
  </div>`,
  
  data () {
    return {
      fname: '',
      lname: '',
      submittedFname: '',
      submittedLname: ''
    }
  },
  methods: {
    handleSubmit() {
      this.submittedFname = this.fname;
      this.submittedLname = this.lname;
    }
  }
});


//child component
Vue.component('name-comp', {
  template: `
  <div>
    <label>Your name is:</label>
    {{ submittedFname }} {{ submittedLname }}
  </div>`,
  
  props: {
    submittedFname: String,
    submittedLname: String
  }
});

var vapp = new Vue({
  el: '#app',
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <app />
</div>

You were missing ":" in front of your props given to the Name component. Also you didn't use this like in this.lname.