0
votes

I have two component

My first component like this :

<template>
    <div>
        ...
            <form-input id="name" name="name" v-model="name">Name</form-input>
        ...
        <button type="submit" class="btn btn-primary" @click="submit">Submit</button>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                name: null
            }
        },
        methods: {
            submit() {
                console.log('submit profile')
                console.log(this.name)
            }
        }
    }
</script>

On the first component, it will call form input component

The form input component like this :

<template>
    <div class="form-group">
        <label :for="id" class="col-sm-3 control-label"><slot></slot></label>
        <div class="col-sm-9">
            <input :type="type" :name="name" :id="id" class="form-control">
        </div>
    </div>
</template>
<script>
    export default {
        props: {
            'id': String,
            'name': String,
            'type': {
                type: String,
                default() {
                    if(this.type == 'number')
                        return 'number'
                    return 'text'
                }
            },
        }
    }
</script>

I using pattern like that. So the form input component can be used in many components

But my problem here is : I can not retrieve the value when submitting button

I try like that, but the result of console.log(this.name) is null

I want when input data name and submit form, it will get the name

How can I solve this problem?

1

1 Answers

2
votes

From the official docs Form Input Components using Custom Events:

  • Know that v-model in the parent is the same as:

    <child-component
       v-bind:value="something"
       v-on:input="something = $event.target.value">
    

So when using v-model you are actually "sending" a value prop and "expecting" an input event.

To make that happen, then, in the child component do:

  • Declare the prop value
  • Change the <input> to have as :value the value prop declared above
  • Change the <input> to emit an input event to its parent when changing value

Final template:

<template>
    <div class="form-group">
        <label :for="id" class="col-sm-3 control-label"><slot></slot></label>
        <div class="col-sm-9">
            <input :type="type" :name="name" :id="id" class="form-control" :value="value" @input="$emit('input', $event.target.value)">
        </div>
    </div>
</template>
<script>
    export default {
        props: {
            'id': String,
            'name': String,
            'type': {
                type: String,
                default() {
                    if(this.type == 'number')
                        return 'number'
                    return 'text'
                }
            },
            'value': String,
        }
    }
</script>