Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend Vue.js v-on:click directive

I'm new to vuejs. I'm trying to create my first app. I would like to show a confirm message on every click on buttons.

Example:

<button class="btn btn-danger" v-on:click="reject(proposal)">reject</button>

My question is: Can I extend the v-on:click event to show the confirm everywhere? I would make my custom directive called v-confirm-click that first executes a confirm and then, if I click on "ok", executes the click event. Is it possible?

like image 639
LorenzoBerti Avatar asked Jul 25 '17 15:07

LorenzoBerti


People also ask

How do you extend Vue?

You use Vue. extend to create component definition (called "component constructor" in old documentation) and Vue. component to register it so it can be used in template to actually create component instance. However, everywhere in Vue API where you can pass "component constructor" created by Vue.

Can you extend a Vue component?

Extending Components The pattern we will highlight today is the extends option (part of the Vue options API) that allows us to compose components and share functionality throughout different parts of your UI in a manageable, concise pattern.

What is V-on in VUE JS?

The v-on:click directive is a Vue. js directive used to add a click event listener to an element. First, we will create a div element with id as app and let's apply the v-on:click directive to a element. Further, we can execute a function when click even occurs.

What is @input in VUE JS?

It provides two-way data binding by binding the input text element and the value binded to a variable assigned.


2 Answers

I would recommend a component instead. Directives in Vue are generally used for direct DOM manipulation. In most cases where you think you need a directive, a component is better.

Here is an example of a confirm button component.

Vue.component("confirm-button",{
  props:["onConfirm", "confirmText"],
  template:`<button @click="onClick"><slot></slot></button>`,
  methods:{
    onClick(){
      if (confirm(this.confirmText))
        this.onConfirm()
    }
  }

})

Which you could use like this:

<confirm-button :on-confirm="confirm" confirm-text="Are you sure?">
  Confirm
</confirm-button>

Here is an example.

console.clear()

Vue.component("confirm-button", {
  props: ["onConfirm", "confirmText"],
  template: `<button @click="onClick"><slot></slot></button>`,
  methods: {
    onClick() {
      if (confirm(this.confirmText))
        this.onConfirm()
    }
  }

})

new Vue({
  el: "#app",
  methods: {
    confirm() {
      alert("Confirmed!")
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <confirm-button :on-confirm="confirm" confirm-text="Are you sure?">
    Confirm
  </confirm-button>
</div>
like image 54
Bert Avatar answered Sep 21 '22 22:09

Bert


I do not know of a way to extend a directive. It is easy enough to include a confirm call in the click handler. It won't convert every click to a confirmed click, but neither would writing a new directive; in either case, you have to update all your code to use the new form.

new Vue({
  el: '#app',
  methods: {
    reject(p) {
      alert("Rejected " + p);
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
  <button class="btn btn-danger" @click="confirm('some message') && reject('some arg')">reject</button>
</div>
like image 31
Roy J Avatar answered Sep 19 '22 22:09

Roy J