13
votes

I'm trying to build a simple app in vue and I'm getting an error. My onScroll function behaves as expected, but my sayHello function returns an error when I click my button component

Property or method "sayHello" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in component )

Vue.component('test-item', {
    template: '<div><button v-on:click="sayHello()">Hello</button></div>'
});

var app = new Vue({
    el: '#app',
    data: {
        header: {
            brightness: 100
        }
    },
    methods: {
        sayHello: function() {
            console.log('Hello');
        },
        onScroll: function () {
            this.header.brightness = (100 - this.$el.scrollTop / 8);
        }
    }
});

I feel like the answer is really obvious but I've tried searching and haven't come up with anything. Any help would be appreciated.

Thanks.

2
sayHello isn't a method of test-item. It's a method of app.ceejayoz
Thanks @ceejayoz, that did it. I did read that here: vuejs.org/guide/components.html that each component is contained in its own isolated scope. So, my component doesn't inherit the methods that I give to the root Vue instance?James Myers
Gotcha. Very interesting, thanks again. I'll mark your answer as correct, cheers.James Myers
It takes a bit of getting used to, but you'll love it as you architect large apps in Vue.ceejayoz

2 Answers

8
votes

But for a few specific circumstances (mainly props) each component is completely isolated from each other. Separate data, variables, functions, etc. This includes their methods.

Thus, test-item has no sayHello method.

2
votes

You can get rid of the warning by using .mount('#app') after the Vue instance rather than the el attribute.

Check the snippet below;

var app = new Vue({
    data: {
        header: {
            brightness: 100
        }
    },
    methods: {
        sayHello: function() {
            console.log('Hello');
        },
        onScroll: function () {
            this.header.brightness = (100 - this.$el.scrollTop / 8);
        }
    }
}).mount('#app');

Please note; the following might not be necessary but did it along the way trying to solve the same issue: Laravel Elixir Vue 2 project.