3

So I'd like to programmatically add an event, e.g. @click depending if on another variable. I can't really use a ref to do something like this.$refs.example.addEventListner("click", someFunction) because I'm doing it for a v-for

I've tried doing something like @click="clickable ? clicked : null" but the function isn't bound even when clickable is true

<template>
  <div id="app">
    <div class="main" @click="clickable ? clicked : null">
    </div>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  data() {
    return {
      clickable: false
    };
  },
  methods: {
    clicked() {
      console.log("clicked");
    }
  },
  components: {
    HelloWorld
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.main {
  background-color: yellow;
  height: 200px;
  width: 400px;
}
</style>

https://codesandbox.io/s/m941978v9x

2 Answers 2

4

Adding () would allow it to be executed.

@click="clickable ? clicked() : null"

https://codesandbox.io/s/p9l4ozx60x


For more complex conditional statements, you could filter the method using computed.

Demo https://codesandbox.io/s/wnv6kjq2wk

<div class="main" @click="clickedMaybe">
</div>

and

  computed:{
    clickedMaybe(){
      if(this.clickable) return this.clicked;
      return function(){};
    }
  },
Sign up to request clarification or add additional context in comments.

2 Comments

That's interesting. Didn't think you'd need to use () to make it executable since the default @click allows you to pass a function without it. Will mark when can
I think Vue will automatically detect whether what's provided is a method name or a Javascript statement. clickable ? clicked : null is a statement. I think that Vue's too magical sometimes that it causes confusion.
0

Try this code, You can conditionally render the DOM node, I tried it and it's working like charm.

<template>
  <div id="app">

    <div class="main" v-if="clickable" @click="clicked"></div>
    <div class="main" v-if="!clickable"></div>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  data() {
    return {
      clickable: true
    };
  },
  methods: {
    clicked() {
      console.log("clicked");
    }
  },
  components: {
    HelloWorld
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.main {
  background-color: yellow;
  height: 200px;
  width: 400px;
}
</style>

2 Comments

works nice when it's simply just got 1 props, but I've got like 10 props and events on it, so making a secondary node just to enable 1 event is too much bloat.
@A.Lau Right. but try consol log this in both the cases.

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.