Tyler Mills
Tyler Mills

Reputation: 363

Vue Component Cannot Find Prop

Pretty basic implementation of Vue here as a test run, and I'm having some issues breaking out data into components. Here is HTML:

<body>
    <header id="main-header">
       <custom-header></custom-header>
    </header>
</body>

I am instantiating a Vue instance and tying it to the #main-header:

import CustomHeader from '../header.vue';

chx = {
    dates: { dateFormatted:"2016-01-01"},
    title: "Hello World",
    settingsVisible: false
} 

const header = new Vue({
    el: '#main-header',
    data: chx,
    components: {
        'custom-header': CustomHeader
    },
    methods: {
        run: function() {
            console.log('run');
        },
        print: function() {
            window.print()
        },
        save: function() {
            console.log('save');
        }
    }
});

And the imported template:

<template>
<div>
    <div class="header-menu">
        <img class="logo" src="images/logo.png">
    </div>
    <i v-on:click="run" id="run" class="fa fa-3x fa-play-circle run-icon no-print" aria-hidden="true"></i>
    <div class="header-menu">
        <h1 id="date-range-label"><span v-show="dates.startFormatted">{{dates.startFormatted}} - {{dates.endFormatted}}</span></h1>
        <i v-on:click="settingsVisible = !settingsVisible" id="settings" class="fa fa-2x fa-cog settings-icon no-print"></i>
    </div>
</div>
</template>

<script>
    export default {
        props: ['title', 'dates']
    }
</script>

My biggest issue is that my template cannot find any of the data from the chx object that I've created. I get the error "TypeError: Cannot read property 'startFormatted' of undefined". I assume I may have to use bind but I'm not sure how the works in conjunction with v-show and v-on.

Upvotes: 0

Views: 1986

Answers (1)

ironcladgeek
ironcladgeek

Reputation: 1130

For the first part you need to define a prop in header.vue component like so:

props: {
    'propname': { type: Object }
}

and then pass the chx object that you created in parent component:

<custom-header :propname="chx"></custom-header>

now you can access the parent's data in child component like this:

{{ propname.dates.startFormatted }}

For the second part of the question, you need to fire an event to notify the parent component to update the settingsVisible. You can tackle that this way:

<i v-on:click="toggleSettings()" id="settings" class="..."></i>
//
//
methods: {
    toggleSettings() { this.$emit('toggle'); }
}

and in parent component listen for toggle event:

<custom-header :propname="chx" v-on:toggle="chx.settingsVisible = !chxsettingsVisible"></custom-header>

You can get more information by reading this document page.

Happy coding!

Upvotes: 2

Related Questions