1

I wrote a basic vue js 2 basic example to test nested components.

Below is components and template structure.

    Vue.component('form-com', {
        template: '#form',
        props: ['value'],
        methods: {
            onInput: function (event) {
                this.$emit('input', event.target.value);
            }
        }
    });

    Vue.component('message-com', {
        template: '#message',
        data: function () {
            return {
                msg: 'Hello'
            }
        },
        props: ['user']
    });

    Vue.component('welcome-com', {
        template: '#welcome',
        data: function () {
            return {
                user: 'ahmad'
            }
        }
    });

    new Vue({
        el: '#container'
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>

<!--Form Template-->
<template id="form">
    <div>
        <div class="form-control">
            <label>Enter Your Name:</label>
            <input type="text" v-bind:value="value" :input="onInput">
        </div>
    </div>
</template>

<!--Hello Message Template-->
<template id="message">
    <div>
        <h3>{{msg}} {{user}}</h3>
    </div>
</template>

<template id="welcome">
    <div>
        <form-com :value="value"></form-com>
        <br>
        <message-com :user="user"></message-com>
    </div>
</template>

<div id="container">
    <welcome-com></welcome-com>
</div>

But when run app in browser this error is shown:

[Vue warn]: Property or method "value" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

found in

---> <WelcomeCom>
       <Root>

what is problem?

Update:

I just Rewrite this Fiddle from one of chapters of Learning Vue.js 2. I just rename some parameters and component and templates names. but when I copy main fiddle to my code all things worked.

2 Answers 2

2

In your form-com component you can set up a v-model which binds the input value and set up a watcher to observer the changes in the input which in turn emits an custom-event which tells the parent component that a change has taken place.

Vue.component('form-com', {
        template: '#form',
        data(){
            return{
                myInput:''
            }
        },
        watch: {
            myInput: function (inputVal) {
                this.$emit('input', inputVal);
            }
        }
    });

    Vue.component('message-com', {
        template: '#message',
        data: function () {
            return {
                msg: 'Hello'
            }
        },
        props: ['user']
    });

    Vue.component('welcome-com', {
        template: '#welcome',
        data: function () {
            return {
                user: 'ahmad'
            }
        },
        methods:{
            updateUser(value){
                this.user = value;
            }
        }
    });

    new Vue({
        el: '#container'
    })

You can listen to the events emitted from the child **form-com ** component using v-on:input or shorthand @input directly in the parent template (welcome component) where the child component is used.

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>

<!--Form Template-->
<template id="form">
    <div>
        <div class="form-control">
            <label>Enter Your Name:</label>
            <input type="text" v-model="myInput">
        </div>
    </div>
</template>

<!--Hello Message Template-->
<template id="message">
    <div>
        <h3>{{msg}} {{user}}</h3>
    </div>
</template>

<template id="welcome">
    <div>
        <form-com @input="updateUser($event)" ></form-com>
        <br>
        <message-com :user="user"></message-com>
    </div>
</template>

<div id="container">
    <welcome-com></welcome-com>
</div> 

Here is the jsFiddle

If you don't want to use a watcher then you can do it using computed setter . Have a look at the fiddle which is using a computed-setter

Sign up to request clarification or add additional context in comments.

Comments

2

You are missing in your Component 'welcome-com' the value object:

Vue.component('welcome-com', {
        template: '#welcome',
        data: function () {
            return {
                value: '',
                user: 'ahmad'
            }
        }
    });

3 Comments

Problem is solved and that error removed. but now when enter some char on the input {msg} does not change.what is problem of this one ?
You never declared that your msg should change. Maybe open another question with what you are trying to accomplish.
I mistake prev comment. I mean {user} param. I want to change user via input text

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.