Releases: f/vue-wait
v1.5.0
1.4.6
Multiple Process Loader Management for Vue and (optionally) Vuex.
Read the Medium post "Managing Complex Waiting Experiences on Web UIs".
vue-wait helps to manage multiple loading states on the page without any conflict. It's based on a very simple idea that manages an array (or Vuex store optionally) with multiple loading states. The built-in loader component listens its registered loader and immediately become loading state.
⏩Quick Start
If you are a try and learn developer, you can start trying the vue-wait now using codesandbox.io.
1. Install:
yarn add vue-wait
2. Require:
import VueWait from 'vue-wait'
Vue.use(VueWait)
new Vue({
// your vue config
wait: new VueWait(),
})
3. Use in Your Components
<template>
<v-wait for="my list is to load">
<template slot="waiting">
<div>
<img src="loading.gif" />
Loading the list...
</div>
</template>
<ul>
<li v-for="item in myList">{{ item }}</li>
</ul>
</v-wait>
</template>
<script>
export default {
data() {
return {
myList: []
}
},
async created() {
// start waiting
this.$wait.start('my list is to load');
this.myList = await fetch('/my-list-url');
// stop waiting
this.$wait.end('my list is to load');
},
};
</script>
vue-wait has more abilities to make the management easier, please read the complete documentation.
▶️ Detailed Start
📦 Requirements
- Vue.js (v2.0.0+)
🚀 Power Supplies
- Vuex, optionally (v2.0.0+)
🔧 Installation
via CLI:
$ yarn add vue-wait
# or if you using npm
$ npm install vue-wait
via Vue UI:
📖 Usage
import VueWait from 'vue-wait'
Vue.use(VueWait) // add VueWait as Vue plugin
Then you should register wait
property (VueWait
instance) to the Vue instance:
new Vue({
el: '#app',
store,
wait: new VueWait({
// Defaults values are following:
useVuex: false, // Uses Vuex to manage wait state
vuexModuleName: 'wait', // Vuex module name
registerComponent: true, // Registers `v-wait` component
componentName: 'v-wait', // <v-wait> component name, you can set `my-loader` etc.
registerDirective: true, // Registers `v-wait` directive
directiveName: 'wait', // <span v-wait /> directive name, you can set `my-loader` etc.
}),
});
♻️ Usage with Vuex
Simply set useVuex
parameter to true
and optionally override
vuexModuleName
import VueWait from 'vue-wait'
Vue.use(Vuex)
Vue.use(VueWait) // add VueWait as Vue plugin
Then you should register VueWait
module:
new Vue({
el: '#app',
store,
wait: new VueWait({
useVuex: true, // You must pass this option `true` to use Vuex
vuexModuleName: 'vuex-example-module' // It's optional, `wait` by default.
}),
});
Now VueWait
will use Vuex
store for data management which can be traced in Vue DevTools > Vuex
♻️ Usage with Nuxt.js
Add vue-wait/nuxt
to modules section of nuxt.config.js
{
modules: [
// Simple usage
'vue-wait/nuxt'
// Optionally passing options in module configuration
['vue-wait/nuxt', { useVuex: true }]
],
// Optionally passing options in module top level configuration
wait: { useVuex: true }
}
🔁 VueWait
Options
You can use this options for customize VueWait behavior.
Option Name | Type | Default | Description |
---|---|---|---|
accessorName |
String |
"$wait" |
You can change this value to rename the accessor. E.g. if you rename this to $w , your VueWait methods will be accessible by $w.waits(..) etc. |
useVuex |
Boolean |
false |
Use this value for enabling integration with Vuex store. When this value is true VueWait will store data in Vuex store and all changes to this data will be made by dispatching actions to store |
vuexModuleName |
String |
"wait" |
Name for Vuex store if useVuex set to true, otherwise not used. |
registerComponent |
Boolean |
true |
Registers v-wait component. |
componentName |
String |
"v-wait" |
Changes v-wait component name. |
registerDirective |
Boolean |
true |
Registers v-wait directive. |
directiveName |
String |
"v-wait" |
Changes v-wait directive name. |
🌈 Global Template Helpers
vue-wait provides some helpers to you to use in your templates.
All features can be obtained from $wait property in Vue components.
.any
Returns boolean value if any loader exists in page.
<template>
<progress-bar v-if="$wait.any">Please wait...</progress-bar>
</template>
.is(loader String | Matcher)
or .waiting(loader String | Matcher)
Returns boolean value if given loader exists in page.
<template>
<progress-bar v-if="$wait.is('creating user')">Creating User...</progress-bar>
</template>
You can use waiting
alias instead of is
.
<template>
<div v-if="$wait.waiting('fetching users')">
Fetching users...
</div>
</template>
Also you can use matcher to make it more flexible:
Please see matcher library to see how to use matchers.
<template>
<progress-bar v-if="$wait.is('creating.*')">Creating something...</progress-bar>
</template>
.is(loaders Array<String | Matcher>)
or .waiting(loaders Array<String | Matcher>)
Returns boolean value if some of given loaders exists in page.
<template>
<progress-bar v-if="$wait.is(['creating user', 'page loading'])">Creating User...</progress-bar>
</template>
.start(loader String)
Starts the given loader.
<template>
<button @click="$wait.start('creating user')">Create User</button>
</template>
.end(loader String)
Stops the given loader.
<template>
<button @click="$wait.end('creating user')">Cancel</button>
</template>
.progress(loader String, current [, total = 100])
Sets the progress of the given loader.
<template>
<progress min="0" max="100" :value="$wait.percent('downloading')" />
<button @click="$wait.progress('downloading', 10)">Set progress to 10</button>
<button @click="$wait.progress('downloading', 50)">Set progress to 50</button>
<button @click="$wait.progress('downloading', 50, 200)">Set progress to 50 of 200 (25%)</button>
</template>
Completing the Progress
To complete the progress, current
value should be set bigger than 100
.
If you total
is given, current
must be bigger than total
.
<button @click="$wait.progress('downloading', 101)">Set as downloaded (101 of 100)</button>
or
<button @click="$wait.progress('downloading', 5, 6)">Set as downloaded (6 of 5)</button>
.percent(loader String)
Returns the percentage of the given loader.
<template>
<progress min="0" max="100" :value="$wait.percent('downloading')" />
</template>
🏹 Directives
You can use directives to make your template cleaner.
v-wait:visible='"loader name"'
Shows if the given loader is loading.
<template>
<progress-bar v-wait:visible='"creating user"'>Creating User...</progress-bar>
</template>
v-wait:hidden='"loader name"'
or v-wait:visible.not='"loader name"'
Hides if the given loader is loading.
<template>
<main v-wait:hidden='"creating *"'>Some Content</main>
</template>
v-wait:disabled='"loader name"'
Sets disabled="disabled"
attribute to element if the given loader is loading.
<template>
<input v-wait:disabled="'*'" placeholder="Username" />
<input v-wait:disabled="'*'" placeholder="Password" />
</template>
v-wait:enabled='"loader name"'
or v-wait:disabled.not='"loader name"'
Removes disabled="disabled"
attribute to element if the given loader is loading.
<template>
<button v-wait:enabled='"creating user"'>Abort Request</button>
</template>
v-wait:click.start='"loader name"'
Starts given loader on click.
<template>
<button v-wait:click.start='"create user"'>Start loader</button>
</template>
v-wait:click.end='"loader name"'
Ends given loader on click.
<template>
<button v-wait:click.end='"create user"'>End loader</button>
</template>
v-wait:toggle='"loader name"'
Toggles given loader on click.
<template>
<button v-wait:toggle='"flip flop"'>Toggles the loader</button>
</template>
v-wait:click.progress='["loader name", 80]'
Sets the progress of given loader on click.
<template>
<button v-wait:click.progress='["downloading", 80]'>Set the "downloading" loader to 80</button>
</template>
🔌 Loading Action and Getter Mappers
vue-wait provides mapWaitingActions
and mapWaitingGetters
mapper to be used with your Vuex stores.
Let's ...
v1.4.6
v1.4.5
v1.4.4
v1.4.2
Transitions
- Added transitions support (thanks @sametaylak)