title: Can you pass an external function to a Vue component as a prop?
body: <p>I have a legacy codebase mostly built in PHP. I'm researching how to turn commonly used parts of the code into re-usable Vue components that can be plugged in as needed.</p>
  <p>In one case, I have an onclick event in the html which will need to be individually passed to a child component. <code>onclick=&quot;func()&quot;</code></p>
  <p>I want to be able to pass that func to the component from the markup, without defining this one-time use function as a property method either on the component or its parents.</p>
  <p>I can't find anything in the Vue docs or elsewhere on how to do that. Every attempt I make gives an error:</p>
  <blockquote>
  <p>Property or method &quot;hi&quot; is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: <a href="https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties" rel="nofollow noreferrer">https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties</a>.</p>
  </blockquote>
  <p>Is there a way to pass externally-defined functions in the global scope to a Vue instance?</p>
  <p>Vue tabs:</p>
  <pre class="lang-js prettyprint-override"><code>Vue.config.devtools = true;
  
  
  Vue.component('tabs', {
    template: `
      &lt;div class=&quot;qv-tabs&quot;&gt;
        &lt;div class=&quot;tab&quot;&gt;
          &lt;ul&gt;
            &lt;li v-for=&quot;tab in tabs&quot;
                :class=&quot;{'is-active' : tab.isActive}&quot;
                @click=&quot;tab.callHandler&quot;
            &gt; 
              &lt;a :href=&quot;tab.href&quot; @click=&quot;selectTab(tab)&quot;&gt;{{tab.name}}&lt;/a&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
        &lt;div class=&quot;tab-content&quot;&gt;
          &lt;slot&gt;&lt;/slot&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    `,
    data(){
      return{
        tabs: []
      };
    },
    created(){
      this.tabs = this.$children;
    },
    methods:{
      selectTab(selectedTab){
        this.tabs.forEach(tab =&gt; {
          tab.isActive = (tab.name == selectedTab.name);
        });
      },
      otherHi() {
        alert('other hi');
      }
    }
  });
  
  Vue.component('tab', {
    template: `
      &lt;div v-show=&quot;isActive&quot;&gt;
        &lt;slot&gt;&lt;/slot&gt;
      &lt;/div&gt;
    `,
    props: {
      name: {required: true},
      selected: {default: false},
      callHandler: Function,
      clickHandler: {
        type: Function,
        default: function() { console.log('default click handler') }
      }
    },
    data(){
      return{
        isActive: false
      }
    },
    methods: {
      callHandler() {
        console.log('call handler called');
        this.clickHandler();
      }
    },
    computed:{
      href(){
        return '#' + this.name.toLowerCase().replace(/ /g, '-');
      }
    },
    mounted(){
      this.isActive = this.selected;
    }
  });
  
  new Vue({
    el: '.app',
    methods: {
      vueHi() { alert('hi from vue'); }
    }
  });
  
  function hi() {
    alert('hi!');
  }
  </code></pre>
  <p>Markup:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;div class=&quot;app&quot;&gt;
      &lt;tabs&gt;
        &lt;tab name=&quot;Tab 1&quot; :selected=&quot;true&quot; v-bind:call-handler=&quot;hi&quot;&gt;
          &lt;p&gt;Tab content&lt;/p&gt;
        &lt;/tab&gt;
        &lt;tab name=&quot;Tab 2&quot;&gt;
          &lt;p&gt;Different content for Tab 2&lt;/p&gt;
        &lt;/tab&gt;
      &lt;/tabs&gt;
    &lt;/div&gt;
  </code></pre>