Trigger a Vue components method by property











up vote
1
down vote

favorite
1












Is it possible to trigger a Vue components method by handling the methods name to one of it's properties?



// main.vue
<navigation :button-left="goback()"></navigation>



// navigation.component.vue
...
props: ["buttonLeft"],
...
methods: {
goback() {
console.log('Run this.');
},
},
...


I tried it like this but it gives me an error:




[Vue warn]: Property or method "goback" 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: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.











share|improve this question
























  • what's your use case?
    – Boussadjra Brahim
    Nov 21 at 22:37










  • The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
    – Mountain
    Nov 21 at 22:42










  • What is meant to trigger the method execution?
    – Phil
    Nov 21 at 22:47










  • did you try to emit events from child component to the parent component and do what you want in the parent?
    – Boussadjra Brahim
    Nov 22 at 14:18















up vote
1
down vote

favorite
1












Is it possible to trigger a Vue components method by handling the methods name to one of it's properties?



// main.vue
<navigation :button-left="goback()"></navigation>



// navigation.component.vue
...
props: ["buttonLeft"],
...
methods: {
goback() {
console.log('Run this.');
},
},
...


I tried it like this but it gives me an error:




[Vue warn]: Property or method "goback" 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: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.











share|improve this question
























  • what's your use case?
    – Boussadjra Brahim
    Nov 21 at 22:37










  • The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
    – Mountain
    Nov 21 at 22:42










  • What is meant to trigger the method execution?
    – Phil
    Nov 21 at 22:47










  • did you try to emit events from child component to the parent component and do what you want in the parent?
    – Boussadjra Brahim
    Nov 22 at 14:18













up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





Is it possible to trigger a Vue components method by handling the methods name to one of it's properties?



// main.vue
<navigation :button-left="goback()"></navigation>



// navigation.component.vue
...
props: ["buttonLeft"],
...
methods: {
goback() {
console.log('Run this.');
},
},
...


I tried it like this but it gives me an error:




[Vue warn]: Property or method "goback" 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: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.











share|improve this question















Is it possible to trigger a Vue components method by handling the methods name to one of it's properties?



// main.vue
<navigation :button-left="goback()"></navigation>



// navigation.component.vue
...
props: ["buttonLeft"],
...
methods: {
goback() {
console.log('Run this.');
},
},
...


I tried it like this but it gives me an error:




[Vue warn]: Property or method "goback" 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: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.








javascript vue.js vuejs2 vue-component






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 at 22:35

























asked Nov 21 at 22:16









Mountain

417614




417614












  • what's your use case?
    – Boussadjra Brahim
    Nov 21 at 22:37










  • The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
    – Mountain
    Nov 21 at 22:42










  • What is meant to trigger the method execution?
    – Phil
    Nov 21 at 22:47










  • did you try to emit events from child component to the parent component and do what you want in the parent?
    – Boussadjra Brahim
    Nov 22 at 14:18


















  • what's your use case?
    – Boussadjra Brahim
    Nov 21 at 22:37










  • The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
    – Mountain
    Nov 21 at 22:42










  • What is meant to trigger the method execution?
    – Phil
    Nov 21 at 22:47










  • did you try to emit events from child component to the parent component and do what you want in the parent?
    – Boussadjra Brahim
    Nov 22 at 14:18
















what's your use case?
– Boussadjra Brahim
Nov 21 at 22:37




what's your use case?
– Boussadjra Brahim
Nov 21 at 22:37












The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
– Mountain
Nov 21 at 22:42




The intention is to handle routing with the navigation. The buttons of the navigation differ from page to page. For some buttons it's necessary to handle a fixed routing path but for others it's just intended to go one step back in the routing history which should be done by a simple method.
– Mountain
Nov 21 at 22:42












What is meant to trigger the method execution?
– Phil
Nov 21 at 22:47




What is meant to trigger the method execution?
– Phil
Nov 21 at 22:47












did you try to emit events from child component to the parent component and do what you want in the parent?
– Boussadjra Brahim
Nov 22 at 14:18




did you try to emit events from child component to the parent component and do what you want in the parent?
– Boussadjra Brahim
Nov 22 at 14:18












2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










Yes, this is definitely possible.



The easiest way would be to pass a plain string, eg



<navigation button-left="goback" />


Note there's no v-bind.



Then in your component, you can use the prop value. Something like...



export default {
template: `<button @click="runButtonLeft">Go</button>`,
props: ['buttonLeft'],
methods: {
runButtonLeft () {
if (typeof this[this.buttonLeft] === 'function') {
this[this.buttonLeft]()
} else {
console.error('Invalid method name:', this.buttonLeft)
}
},
goback () {
console.log('Run this.')
}
}
}


You didn't specify what should be used to trigger the method execution so I've gone with a click event.






share|improve this answer





















  • Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
    – John Halsey
    Nov 22 at 13:42










  • I adopted this way and it fits my need. This is right for me. Thanks a lot.
    – Mountain
    Nov 24 at 18:37


















up vote
0
down vote













You could assign a method to property and pass parameters as you like, the returned variable from the method will be the property value.



Note : the method should be defined in the parent component like in the following example :






// ignore the following two lines, they just disable warnings in "Run code snippet"
Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component("nav-cmp", {

props: ["btnLeft", "btnRight"],

template: `<div>
<h1>{{btnLeft}}</h1>
<h2>{{btnRight}}</h2>
</div>`
});


new Vue({
el: '#app',

data() {
return {

}
},
methods: {
goback(p) {
console.log(p)
return p;
}

}
});

<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


<div id="app" class="container">
<nav-cmp :btn-left="goback('btn left')"></nav-cmp>
<nav-cmp :btn-right="goback('btn right')"></nav-cmp>

</div>








share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421207%2ftrigger-a-vue-components-method-by-property%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    Yes, this is definitely possible.



    The easiest way would be to pass a plain string, eg



    <navigation button-left="goback" />


    Note there's no v-bind.



    Then in your component, you can use the prop value. Something like...



    export default {
    template: `<button @click="runButtonLeft">Go</button>`,
    props: ['buttonLeft'],
    methods: {
    runButtonLeft () {
    if (typeof this[this.buttonLeft] === 'function') {
    this[this.buttonLeft]()
    } else {
    console.error('Invalid method name:', this.buttonLeft)
    }
    },
    goback () {
    console.log('Run this.')
    }
    }
    }


    You didn't specify what should be used to trigger the method execution so I've gone with a click event.






    share|improve this answer





















    • Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
      – John Halsey
      Nov 22 at 13:42










    • I adopted this way and it fits my need. This is right for me. Thanks a lot.
      – Mountain
      Nov 24 at 18:37















    up vote
    0
    down vote



    accepted










    Yes, this is definitely possible.



    The easiest way would be to pass a plain string, eg



    <navigation button-left="goback" />


    Note there's no v-bind.



    Then in your component, you can use the prop value. Something like...



    export default {
    template: `<button @click="runButtonLeft">Go</button>`,
    props: ['buttonLeft'],
    methods: {
    runButtonLeft () {
    if (typeof this[this.buttonLeft] === 'function') {
    this[this.buttonLeft]()
    } else {
    console.error('Invalid method name:', this.buttonLeft)
    }
    },
    goback () {
    console.log('Run this.')
    }
    }
    }


    You didn't specify what should be used to trigger the method execution so I've gone with a click event.






    share|improve this answer





















    • Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
      – John Halsey
      Nov 22 at 13:42










    • I adopted this way and it fits my need. This is right for me. Thanks a lot.
      – Mountain
      Nov 24 at 18:37













    up vote
    0
    down vote



    accepted







    up vote
    0
    down vote



    accepted






    Yes, this is definitely possible.



    The easiest way would be to pass a plain string, eg



    <navigation button-left="goback" />


    Note there's no v-bind.



    Then in your component, you can use the prop value. Something like...



    export default {
    template: `<button @click="runButtonLeft">Go</button>`,
    props: ['buttonLeft'],
    methods: {
    runButtonLeft () {
    if (typeof this[this.buttonLeft] === 'function') {
    this[this.buttonLeft]()
    } else {
    console.error('Invalid method name:', this.buttonLeft)
    }
    },
    goback () {
    console.log('Run this.')
    }
    }
    }


    You didn't specify what should be used to trigger the method execution so I've gone with a click event.






    share|improve this answer












    Yes, this is definitely possible.



    The easiest way would be to pass a plain string, eg



    <navigation button-left="goback" />


    Note there's no v-bind.



    Then in your component, you can use the prop value. Something like...



    export default {
    template: `<button @click="runButtonLeft">Go</button>`,
    props: ['buttonLeft'],
    methods: {
    runButtonLeft () {
    if (typeof this[this.buttonLeft] === 'function') {
    this[this.buttonLeft]()
    } else {
    console.error('Invalid method name:', this.buttonLeft)
    }
    },
    goback () {
    console.log('Run this.')
    }
    }
    }


    You didn't specify what should be used to trigger the method execution so I've gone with a click event.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 21 at 22:51









    Phil

    95.1k11135154




    95.1k11135154












    • Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
      – John Halsey
      Nov 22 at 13:42










    • I adopted this way and it fits my need. This is right for me. Thanks a lot.
      – Mountain
      Nov 24 at 18:37


















    • Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
      – John Halsey
      Nov 22 at 13:42










    • I adopted this way and it fits my need. This is right for me. Thanks a lot.
      – Mountain
      Nov 24 at 18:37
















    Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
    – John Halsey
    Nov 22 at 13:42




    Yes this would work, but I'm struggling to think of a use case for this. If you want different functionality of an event (button left in this case) every time you implement the component, I would probably emit that he event happened, and let the parent component decide what needs to happen. Like <navigation @button-left="call-some-method-on-parent-component" />
    – John Halsey
    Nov 22 at 13:42












    I adopted this way and it fits my need. This is right for me. Thanks a lot.
    – Mountain
    Nov 24 at 18:37




    I adopted this way and it fits my need. This is right for me. Thanks a lot.
    – Mountain
    Nov 24 at 18:37












    up vote
    0
    down vote













    You could assign a method to property and pass parameters as you like, the returned variable from the method will be the property value.



    Note : the method should be defined in the parent component like in the following example :






    // ignore the following two lines, they just disable warnings in "Run code snippet"
    Vue.config.devtools = false;
    Vue.config.productionTip = false;

    Vue.component("nav-cmp", {

    props: ["btnLeft", "btnRight"],

    template: `<div>
    <h1>{{btnLeft}}</h1>
    <h2>{{btnRight}}</h2>
    </div>`
    });


    new Vue({
    el: '#app',

    data() {
    return {

    }
    },
    methods: {
    goback(p) {
    console.log(p)
    return p;
    }

    }
    });

    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


    <div id="app" class="container">
    <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
    <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

    </div>








    share|improve this answer

























      up vote
      0
      down vote













      You could assign a method to property and pass parameters as you like, the returned variable from the method will be the property value.



      Note : the method should be defined in the parent component like in the following example :






      // ignore the following two lines, they just disable warnings in "Run code snippet"
      Vue.config.devtools = false;
      Vue.config.productionTip = false;

      Vue.component("nav-cmp", {

      props: ["btnLeft", "btnRight"],

      template: `<div>
      <h1>{{btnLeft}}</h1>
      <h2>{{btnRight}}</h2>
      </div>`
      });


      new Vue({
      el: '#app',

      data() {
      return {

      }
      },
      methods: {
      goback(p) {
      console.log(p)
      return p;
      }

      }
      });

      <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


      <div id="app" class="container">
      <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
      <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

      </div>








      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        You could assign a method to property and pass parameters as you like, the returned variable from the method will be the property value.



        Note : the method should be defined in the parent component like in the following example :






        // ignore the following two lines, they just disable warnings in "Run code snippet"
        Vue.config.devtools = false;
        Vue.config.productionTip = false;

        Vue.component("nav-cmp", {

        props: ["btnLeft", "btnRight"],

        template: `<div>
        <h1>{{btnLeft}}</h1>
        <h2>{{btnRight}}</h2>
        </div>`
        });


        new Vue({
        el: '#app',

        data() {
        return {

        }
        },
        methods: {
        goback(p) {
        console.log(p)
        return p;
        }

        }
        });

        <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


        <div id="app" class="container">
        <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
        <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

        </div>








        share|improve this answer












        You could assign a method to property and pass parameters as you like, the returned variable from the method will be the property value.



        Note : the method should be defined in the parent component like in the following example :






        // ignore the following two lines, they just disable warnings in "Run code snippet"
        Vue.config.devtools = false;
        Vue.config.productionTip = false;

        Vue.component("nav-cmp", {

        props: ["btnLeft", "btnRight"],

        template: `<div>
        <h1>{{btnLeft}}</h1>
        <h2>{{btnRight}}</h2>
        </div>`
        });


        new Vue({
        el: '#app',

        data() {
        return {

        }
        },
        methods: {
        goback(p) {
        console.log(p)
        return p;
        }

        }
        });

        <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


        <div id="app" class="container">
        <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
        <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

        </div>








        // ignore the following two lines, they just disable warnings in "Run code snippet"
        Vue.config.devtools = false;
        Vue.config.productionTip = false;

        Vue.component("nav-cmp", {

        props: ["btnLeft", "btnRight"],

        template: `<div>
        <h1>{{btnLeft}}</h1>
        <h2>{{btnRight}}</h2>
        </div>`
        });


        new Vue({
        el: '#app',

        data() {
        return {

        }
        },
        methods: {
        goback(p) {
        console.log(p)
        return p;
        }

        }
        });

        <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


        <div id="app" class="container">
        <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
        <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

        </div>





        // ignore the following two lines, they just disable warnings in "Run code snippet"
        Vue.config.devtools = false;
        Vue.config.productionTip = false;

        Vue.component("nav-cmp", {

        props: ["btnLeft", "btnRight"],

        template: `<div>
        <h1>{{btnLeft}}</h1>
        <h2>{{btnRight}}</h2>
        </div>`
        });


        new Vue({
        el: '#app',

        data() {
        return {

        }
        },
        methods: {
        goback(p) {
        console.log(p)
        return p;
        }

        }
        });

        <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


        <div id="app" class="container">
        <nav-cmp :btn-left="goback('btn left')"></nav-cmp>
        <nav-cmp :btn-right="goback('btn right')"></nav-cmp>

        </div>






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 14:26









        Boussadjra Brahim

        4,3953629




        4,3953629






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421207%2ftrigger-a-vue-components-method-by-property%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Berounka

            Different font size/position of beamer's navigation symbols template's content depending on regular/plain...

            Sphinx de Gizeh