0

I have the need of changing the method that a button executed dynamically. In Javascript, it will be as easy as giving the button and id, for example id="my-button", and then do

document.getElementById("my-button").setAttribute("onclick", "theNewMethodToExecute()")

And just like that, the button will execute the new method. How can I do that in Vue.js?

I have a simple mini-project to show my problem:

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./ts/generated/logic.js" defer></script>
  </head>
  <body>
    <div class="" id="app">
      <p class="">My number is:</p>
      <button @click="methodToExecute"></button>
    </div>
  </body>
</html>

index.ts (I write my Vue app in TypeScript instead of JavaScript, and I use Webpack and npm to compile my result, which compiles to a file called logic.js)

import Vue from 'vue'

const myApp = new Vue({
    data() {
        return {
            methodToExecute: "doNothing",
        };
    },
    methods: {
        doNothing() {
            console.log("Dong nothing...")
            this.methodToExecute = "doSomethingElse"
        },
        doSomethingElse() {
            console.log("Doing something else...")
        },

    },
});

myApp.$mount("#app");

In this case I tried with a property but that not work.

Note: I am aware that I can conditionally change the method like this:

v-on="{click: condition ? doWhenTrue : doWhenFalse}"

But the logic I have is much more complex, and I need to change the method programatically, the way I can do in JavaScript, How is that possible with Vue?

1
  • 2
    Is there some particular reason you need to swap out the click handler instead of having the click handle make the decision of what to do? In other words, instead of trying to attach either doWhenTrue or doWhenFalse in your last example, just attach doTheRightThing and have doTheRightThing evaluate the condition and call the appropriate function then. Commented Oct 6, 2021 at 20:17

1 Answer 1

2

Why don't you put the condition inside the method and pass an argument to it? I'm not sure on what you're trying to achieve but something like this would work for your use case.

<a @click="doNothingOrSomething(condition)"></a>

methods: {
    doNothingOrSomething(arg) {
        if (arg === 'something') {
            console.log("Doing nothing...")
        } else console.log("Doing something else...")
    }
}

Using that reasoning, the result will be:

import Vue from 'vue'

const myApp = new Vue({
    data() {
        return {
            argument: "",
        };
    },
    methods: {
        doNothingOrSomething() {
            switch (this.argument) {
                case "method1": {
                    console.log("Is method 1")
                    this.argument = "method2"
                    break;
                }
                case "method2": {
                    console.log("Is method 2")
                    this.argument = "method3"
                    break;
                }
                case "method3": {
                    console.log("Is method 3")
                    this.argument = "method1"
                    break;
                }
                default: {
                    console.log("default")
                    this.argument = "method1"
                    break;
                }
            }
        }
    },
});

myApp.$mount("#app");

and the HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./ts/generated/logic.js" defer></script>
  </head>
  <body>
    <div class="" id="app">
      <p class="">My number is:</p>
      <button @click="doNothingOrSomething"></button>
    </div>
    <script></script>
  </body>
</html>

And that makes it work dynamically!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.