简体   繁体   中英

VueJS prevent default action on custom event

I have a <btn> component which consists of the following template:

<button @click="$emit('trigger')">
</button>

I use the component in my forms like this:

<btn>Submit</btn>

Now there are situations when I need to have two buttons in the form. One of them submits the form, and the other does not. But because both of them are inside my form, they both submits the form. I cannot do something like this:

<btn>Submit</btn> <!-- This button should submit the form -->
<btn @trigger="nextQuiz">Next</btn> <!-- This button should only execute the nextQuiz method -->

How can I tell vue to to prevent the form submission only when the second <btn> is clicked?

You could specify inline to prevent the default behavior of the native click event via @click.native.prevent :

 Vue.component('btn', { template:` <button @click="$emit('trigger')"> <slot/> </button> ` }) new Vue({ el: '#app', methods: { nextQuiz() { console.log('nextQuiz') } } }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script> <div id="app"> <form action=""> <input name="bar"> <btn>Submit</btn> <btn @click.native.prevent @trigger="nextQuiz">Next</btn> </form> </div> 

Set the type .

Vue.component("btn",{
  props:{
    submit: Boolean
  },
  computed:{
    type() { return this.submit ? 'submit' : 'button' }
  },
  template: `
    <button :type="type"  @click="$emit('trigger')"><slot></slot></button>
  `
})

Used like:

<form action="">
  <btn submit>Submit</btn>
  <btn>Don't Submit</btn>
</form>

Here is an example.

 console.clear() Vue.component("btn",{ props:{ submit: Boolean }, computed:{ type() { return this.submit ? 'submit' : 'button' } }, template: ` <button :type="type" @click="$emit('trigger')"><slot></slot></button> ` }) new Vue({ el: "#app" }) 
 <script src="https://unpkg.com/vue@2.4.2"></script> <div id="app"> <form action=""> <btn submit>Submit</btn> <btn>Don't Submit</btn> </form> </div> 

@thanksd had a similar other idea to one I had. You could also use the prevent modifier.

Vue.component("btn",{
  props:{
    submit: Boolean
  },
  template: `
    <button v-if="submit" @click="$emit('trigger')"><slot></slot></button>
    <button v-else="submit" @click.prevent="$emit('trigger')"><slot></slot></button>
  `
})

As long as your root element is a button (which is in your case), you could also set the type to button, which will pass through to the button. <button type="button">Click</button> natively doesn't submit forms. In your case, <btn type="button">Click</btn> should not submit the form. This keeps your Vue code simpler.

<btn>Submit</btn> <!-- This button should submit the form -->
<btn type="button" @trigger="nextQuiz">Next</btn> <!-- This button should only execute the nextQuiz method -->

See MDN on button type and the HTML Spec for buttons .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM