Features

Installation

import Vue from 'vue'
import VuePromiseBtn from 'vue-promise-btn'

// not required. Styles for built-in spinner
import 'vue-promise-btn/dist/vue-promise-btn.css'

Vue.use(VuePromiseBtn) // or with global options:  Vue.use(VuePromiseBtn, {loader: '...'})

Quick Start

There are 2 modes for this plugin: SIMPLIFIED and EXTENDED

Simplified syntax:

EXTREMELY easy. Just add directive v-promise-btn to your button:

<button v-promise-btn @click="getData">Get Data</button>

Or with single instance options:

<button v-promise-btn="options" @click="getData">Get Data</button>
!!! Event handler should always return Promise for SIMPLIFIED mode

Extended syntax:

Simply add option parameter promise and assing to it promise from data you want to handle.

<button v-promise-btn="{ promise: isLoading }" @click="getData">Get Data</button>
!!! If you face any issue - better to use EXTENDED syntax

Examples

   

<button v-promise-btn @click="asyncAction">Click handler</button>

<button v-promise-btn @click.prevent="asyncAction">With Prevent modifier</button>

<button v-promise-btn="{action: 'contextmenu'}" @click.right="asyncAction">Right mouse</button>

<button v-promise-btn="{action: 'mouseup'}" @click.middle="asyncAction">Middle mouse</button>

<button v-promise-btn="{loader: CustomSpinnerComponent}" @click="asyncAction">Loader as custom component</button>

<button v-promise-btn="{loader: '<b>(HTML loader...)</b>' }" @click="asyncAction">Loader as custom component</button>

<button v-promise-btn v-on="{ click: asyncActionWithArgs($event, 'abc') }">Btn with expression on click handle</button>

!!! Important: if you want to use closure - you have to define v-on="{ click: test('abc') }" instead of @click="test('abc')"

<button v-promise-btn="{ promise: dataPromise }" @click="asyncWithPromiseInData('Hello from async action!')">Extended syntax with external promise</button>

This param allow to use directive with external components. Use this option if you faced issued with simplified syntax

Extended with Vue Bootstrap

<b-btn v-promise-btn="{ promise: bootstrapBtnPromise }" @click="vueBootstrap('Hello from vue bootstrap button!')">Extended with Vue Bootstrap</b-btn>

<form v-promise-btn="{action: 'submit'}" @submit.prevent="asyncAction">
  <button type="submit">Button Form Submit</button>
</form>

Vue.component('custom-form', {
  template: `<form @submit.prevent="$emit('submit', 'data')">
    <p>
      <button type="submit">Button Form Submit - Handle Component Event</button>
    </p>
  </form>`
})

<custom-form @submit="dummyAsyncAction" v-promise-btn="{action: 'submit'}"></custom-form>

Spinner is hidden because it can't be appended into <input type="submit"> element

Options

Option Type Default value
btnLoadingClass String loading
spinnerHiddenClass String hidden
action String click
disableBtn Boolean true
minTimeout Number 400
autoHideSpinnerWrapper Boolean false (if true - add display property that depends on spinner state)
loader Component or HTML String Built-in Spinner component
stringHTMLRenderer Function Returns HTML string template
componentRenderer Function Returns component render-function

Action types

Vue internal action names for mouse modifiers

Mouse Modifier Action Name
Left click
Right contextmenu
Middle mouseup

Limitations