Przemek
Przemek

Reputation: 822

Vue.js Property or method "hello" is not defined on the instance but referenced during render

I have a navigation as a component in vue:

<template>
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse">
        <span class="navbar-toggler-icon"></span>
    </button>
        <a class="navbar-brand" href="">Website Builder</a>
        <div class="collapse navbar-collapse" id="navbarCollapse">
            <ul class="navbar-nav nav-fill w-100">
                <li class="nav-item">
                    <a class="nav-link" href="/#/create">Create</a>
                </li>
                <li class="nav-item">
                    <a v-on:click="hello" class="nav-link" href="/#/how">How</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/#/about">About</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/#/youtube">Videos</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="/#/login">Go to main site</a>
                </li>
            </ul>
    </div>
</nav>
</template>

<script>

export default {
    data() {
        return {

        }
    },
    methods: //if I have hello function here it works
}

</script>

And my vue setup looks like this:

import Navigation from '../components/homeNavigation.vue';


Vue.component('navigation', Navigation);



new Vue({
    el: '#nav',
    methods:
        hello: function () {
            console.log('hi');
        } // I want it here so that it is available for all components within '#nav'
});

So basically I want to define it in new Vue so that is available across all components i.e if I would have another component inside #nav that function would work too. Can that be achieved or does it have to be within component itself?

Upvotes: 0

Views: 3653

Answers (3)

Bsalex
Bsalex

Reputation: 2970

Yes, you can do it with a plugin.
https://v2.vuejs.org/v2/guide/plugins.html

Vue.component('someComponent', {
  template: `
        <span>
            Example text <br/>
            {{globalMethod()}}
        </span>
  `
});


const MyPlugin = {
  install(Vue) {
    Vue.prototype.globalMethod = function () {
      return 'Global method result';
    }
  }
};

Vue.use(MyPlugin);

var instance = new Vue({
  el: '.app',
  template: '<someComponent />'
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div class="app"></div>

Upvotes: 1

bbsimonbb
bbsimonbb

Reputation: 29022

If you want to call a method on 'navigation' from a child component, you can do it with this.$parent.hello(), but Vue components don't (shouldn't) call methods on their parents. Components declare their properties, and parents can provide them or not. Components can emit events, which parents can catch, or not. You should avoid directly calling methods.

Upvotes: 0

craig_h
craig_h

Reputation: 32734

If you want to reuse methods across components you should use a mixin which will merge the mixin methods into the given component:

const HelloMixin = {
  methods: {
    hello() {
      console.log('hi');
    }
  }
}

new Vue({
  el: '#app',
  mixins: [HelloMixin],
  created() {
    this.hello();
  },
})

Here's the JSFiddle: https://jsfiddle.net/taxq569t/

Upvotes: 4

Related Questions